1. 程式人生 > >JavaEE學習之Spring AOP

JavaEE學習之Spring AOP

一、基本概念

  AOP——Aspect-Oriented Programming,面向切面程式設計,它是spring框架的一個重要組成部分。一般的業務邏輯都有先後關係,我們可以理解為縱向關係,而AOP關注的是橫向關係,每一個關注點可以理解為一個橫切面。例如我們的大部分程式碼都會涉及到日誌記錄,很多的資料庫操作都會涉及到事務的建立和提交。那麼從橫向關注這些邏輯,他們都一個個的切面。

  AOP技術的具體實現,可以通過動態代理技術或者是在程式編譯期間進行靜態的"織入"方式。AOP經常使用的場景包括:日誌記錄,事務管理,異常處理,安全控制等方面。Spring 中 AOP 代理由 Spring 的 IoC 容器負責生成、管理,其依賴關係也由 IoC 容器負責管理。在spring中可以僅通過配置檔案實現AOP,也可以使用註解實現。

  AOP相關概念:

  • Aspect(方面,切面):系統中需要實現的那些交叉功能,是系統模組化的一個切面,或領域。如日誌記錄。
  • Joinpoint(連線點):應用程式執行過程中,插入切面的地點,可以是方法呼叫,異常丟擲,或者要修改的欄位。
  • Advice(通知):切面的實際實現,他通知系統新的行為。AOP通知大致上包括:前置通知(Before),環繞通知(Around),後置通知(After Returning),異常通知(Throws Advice) .。
  • Pointcut(切入點):定義了將通知應用到哪一個連線點。本質上是一個捕獲連線點的結構。在AOP中,可以定義一個point cut,來捕獲相關方法的呼叫。
  • Introduce(引入):為物件引入附加的方法或屬性,從而達到修改物件結構的目的。
  • 目標物件:被通知的物件,既可以是你編寫的類,也可以是第三方類。
  • 代理:將通知應用到目標物件後建立的物件,應用系統的其他部分不用為了支援代理物件而改變
  • Weaving(編織,織入):將切面應用到目標物件從而建立一個新代理物件的過程。織入發生在目標物件生命週期的多個點上:編譯器,類裝載期,執行期。

二、依賴jar包

 本文主要學習spring aop相關使用,所以需要的jar主要包括spring相關jar包和aop相關jar包,具體pom.xml檔案如下:

 1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 2   <modelVersion>4.0.0</modelVersion>
 3   <groupId>wzhang</groupId>
 4   <artifactId>spring-aop</artifactId>
 5   <version>0.0.1-SNAPSHOT</version>
 6   <name>spring-aop</name>
 7   <description>Hello World</description>
 8   <dependencies>
 9       <dependency>
10           <groupId>org.springframework</groupId>
11           <artifactId>spring-aop</artifactId>
12           <version>3.2.3.RELEASE</version>
13       </dependency>
14       <dependency>
15           <groupId>org.springframework</groupId>
16           <artifactId>spring-beans</artifactId>
17           <version>3.2.3.RELEASE</version>
18       </dependency>
19       <dependency>
20           <groupId>org.springframework</groupId>
21           <artifactId>spring-context</artifactId>
22           <version>3.2.3.RELEASE</version>
23       </dependency>
24       <dependency>
25           <groupId>org.springframework</groupId>
26           <artifactId>spring-core</artifactId>
27           <version>3.2.3.RELEASE</version>
28       </dependency>
29       <dependency>
30           <groupId>org.springframework</groupId>
31           <artifactId>spring-expression</artifactId>
32           <version>3.2.3.RELEASE</version>
33       </dependency>
34       <dependency>
35           <groupId>aopalliance</groupId>
36           <artifactId>aopalliance</artifactId>
37           <version>1.0</version>
38       </dependency>
39       <dependency>
40           <groupId>log4j</groupId>
41           <artifactId>log4j</artifactId>
42           <version>1.2.17</version>
43       </dependency>
44       <dependency>
45           <groupId>org.aspectj</groupId>
46           <artifactId>aspectjrt</artifactId>
47           <version>1.8.2</version>
48       </dependency>
49       <dependency>
50           <groupId>org.aspectj</groupId>
51           <artifactId>aspectjweaver</artifactId>
52           <version>1.8.2</version>
53       </dependency>
54   </dependencies>
55 </project>
pom.xml

三、具體實現

任何技術都是為業務服務的,AOP也不例外。下面以經典的計算器業務為例,簡單介紹下AOP的應用。

1.利用maven建立一個simple project,並新增相關依賴。

2.在src/main/resources目錄下建立spring配置檔案:applicationContext.xml,先放著,用的時候再去配置。

(***************上面兩步都是準備工作,下面才是具體實現*********************)

3.定義業務類

定義介面:ICalculate,並提供int add(int,int)方法,再定義一個實現類CalculateImpl:

 1 /************** ICalculate介面 **************/
 2 
 3 package com.wzhang.service;
 4 
 5 public interface ICalculate {
 6 
 7     /**
 8      * add 加運算
 9      * @return 兩數和
10      */
11     int add(int a,int b);
12 }
13 
14 /********* ICalculate 的實現類 **************/
15 
16 package com.wzhang.service.impl;
17 
18 import com.wzhang.service.ICalculate;
19 
20 public class CalculateImpl implements ICalculate {
21 
22     public int add(int a, int b) {
23         return a+b;
24     }
25 }

4.spring 實現AOP有兩種方式,配置檔案和註解方式。這裡先通過配置檔案實現方法呼叫前的許可權檢查:

1)定義類SecurityAspect,並提供方法checkAuthority.程式碼如下:

 1 package com.wzhang.aspect;
 2 /**
 3 * 安全檢查切面(方面)
 4 */
 5 public class SecurityAspect {
 6     
 7     /**
 8      * 許可權檢查
 9      */
10     public void checkAuthority(){
11         System.out.println("方法呼叫前,先檢查許可權!");
12     }
13 }

2) 在applicationContext.xml中配置AOP:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
 4     xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
 5     xsi:schemaLocation="http://www.springframework.org/schema/beans 
 6     http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
 7     http://www.springframework.org/schema/context     
 8     http://www.springframework.org/schema/context/spring-context-3.2.xsd
 9     http://www.springframework.org/schema/tx 
10     http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
11     http://www.springframework.org/schema/aop 
12     http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
13 
14     <!-- 掃描com.wzhang下的所有包 -->
15     <context:component-scan base-package="com.wzhang" />
16 
17     <!-- 定義業務類 -->
18     <bean id="calculate" class="com.wzhang.service.impl.CalculateImpl" />
19 
20     <!-- 定義一個安全控制切面 -->
21     <bean id="authority" class="com.wzhang.aspect.SecurityAspect" />
22 
23     <!-- 通過配置檔案實現 -->
24     <aop:config>
25         <!-- 定義切面 -->
26         <aop:aspect id="security" ref="authority">
27             <!-- 指定切入點 -->
28             <aop:pointcut expression="execution(* com.wzhang.service.*.*(..))"
29                 id="securityPointcut" />
30             <!-- 配置前置通知 -->
31             <aop:before method="checkAuthority" pointcut-ref="securityPointcut" />
32             <!-- 還可以配置環繞通知,後置通知,異常通知 -->
33         </aop:aspect>
34     </aop:config>
35 </beans>

注意事項:

  • 需要配置AOP相關的schema;
  • 在<aop:config></aop:config>節點中配置切面,也就是我們之前定義的處理類;
  • 指定切入點,使用切入點表示式。
  • 通知(Advice),可以通過pointcut-ref指定已定義切入點;要定義內建切入點,可將 pointcut-ref 屬性替換為 pointcut 屬性。

經過以上幾步,使用配置檔案實現的主體程式碼就完成了,剩下的就是測試了。我們這裡和用註解實現AOP一起測試

5. 通過註解實現方法呼叫前後的日誌記錄

1)通過註解實現AOP需要在配置檔案中配置:  <aop:aspectj-autoproxy />節點,啟動對@AspectJ註解的支援。配置如下:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
 4     xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
 5     xsi:schemaLocation="http://www.springframework.org/schema/beans 
 6     http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
 7     http://www.springframework.org/schema/context     
 8     http://www.springframework.org/schema/context/spring-context-3.2.xsd
 9     http://www.springframework.org/schema/tx 
10     http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
11     http://www.springframework.org/schema/aop 
12     http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
13     
14     <!-- 掃描com.wzhang下的所有包 -->
15     <context:component-scan base-package="com.wzhang" />
16 
17     <!-- 自動為spring容器中那些配置@aspectJ切面的bean建立代理,織入切面。(啟動對@AspectJ註解的支援) -->
18     <aop:aspectj-autoproxy />
19 </beans>

2)定義切面。程式碼如下:

 1 package com.wzhang.aspect;
 2 
 3 import org.aspectj.lang.annotation.AfterReturning;
 4 import org.aspectj.lang.annotation.Aspect;
 5 import org.aspectj.lang.annotation.Before;
 6 import org.aspectj.lang.annotation.Pointcut;
 7 
 8 /**
 9  * 記錄日誌切面
10  * @author wzhang
11  *
12  */
13 @Aspect
14 public class LogAspect {
15     
16     /**
17      * 前置切入點,
18      */
19     @Pointcut("execution(* com.wzhang.service.*.*(..))")
20     public void beforePointcut(){}
21     
22     /**
23      * 後置通知,日誌記錄
24      */
25     @AfterReturning("execution(* com.wzhang.service.*.*(..))")
26     public void log(){
27         System.out.println("方法呼叫後,記錄操作日誌!");
28     }
29     
30     /**
31      * 前置通知
32      */
33     @Before("beforePointcut()")
34     public void beforeLog(){
35         System.out.println("使用@Pointcut註解,實現方法呼叫前記錄操作日誌!");
36     }
37 
38 }

3)配置bean:<bean id="log" class="com.wzhang.aspect.LogAspect" />,最終配置(包括第4步的配置)如下:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
 4     xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
 5     xsi:schemaLocation="http://www.springframework.org/schema/beans 
 6     http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
 7     http://www.springframework.org/schema/context     
 8     http://www.springframework.org/schema/context/spring-context-3.2.xsd
 9     http://www.springframework.org/schema/tx 
10     http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
11     http://www.springframework.org/schema/aop 
12     http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
13 
14     <!-- 掃描com.wzhang下的所有包 -->
15     <context:component-scan base-package="com.wzhang" />
16 
17     <!-- 定義業務類 -->
18     <bean id="calculate" class="com.wzhang.service.impl.CalculateImpl" />
19 
20     <!-- 定義一個安全控制切面 -->
21     <bean id="authority" class="com.wzhang.aspect.SecurityAspect" />
22     
23     <bean id="log" class="com.wzhang.aspect.LogAspect" />
24 
25     <!-- 通過配置檔案實現 -->
26     <aop:config>
27         <!-- 定義切面 -->
28         <aop:aspect id="security" ref="authority">
29             <!-- 指定切入點 -->
30             <aop:pointcut expression="execution(* com.wzhang.service.*.*(..))"
31                 id="securityPointcut" />
32             <!-- 配置前置通知 -->
33             <aop:before method="checkAuthority" pointcut-ref="securityPointcut" />
34             <!-- 還可以配置環繞通知,後置通知,異常通知 -->
35         </aop:aspect>
36     </aop:config>
37 
38 
39     <!-- 自動為spring容器中那些配置@aspectJ切面的bean建立代理,織入切面。(啟動對@AspectJ註解的支援) -->
40     <aop:aspectj-autoproxy />
41 </beans>
applicationContext.xml

幾點說明:

通過@Aspect註解宣告切面;

通過@Before,@Around,@AfterReturning,@AfterThrowing等定義通知,可以通過表示式execution(xxx)定義切入點;

還可以在方法上@Pointcut定義切入點,方便同類中其他方法使用此處配置的切入點。

6.測試,在src/test/java目錄下建立測試類:AppTest.程式碼如下:

 1 package com.wzhang.test;
 2 
 3 import org.junit.Assert;
 4 import org.junit.Test;
 5 import org.springframework.context.ApplicationContext;
 6 import org.springframework.context.support.ClassPathXmlApplicationContext;
 7 
 8 import com.wzhang.domain.UserBean;
 9 import com.wzhang.service.ICalculate;
10 import com.wzhang.service.IUser;
11 
12 public class AopTest {
13 
14     static ApplicationContext ctx;
15     static {
16         ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
17     }
18     
19     @Test
20     public void calculateTest(){
21         ICalculate cal =  (ICalculate) ctx.getBean("calculate");
22         int result =  cal.add(5, 6);
23         Assert.assertEquals(11, result);
24     }
25 }

執行測試,輸入以下結果:

相關推薦

JavaEE學習Spring AOP

一、基本概念   AOP——Aspect-Oriented Programming,面向切面程式設計,它是spring框架的一個重要組成部分。一般的業務邏輯都有先後關係,我們可以理解為縱向關係,而AOP關注的是橫向關係,每一個關注點可以理解為一個橫切面。例如我們的大部分程式碼都會涉及到日誌記錄,很多的資料庫

SSH框架學習Spring ---- 2、認識AOP ! 警告,前方增強怪!

一、AOP底層分析 需求:根據客戶需要,當前的Dao.class中的add()方法,在呼叫之前需要列印一條"開始列印"語句。 以往的做法: 動add的程式碼,該怎麼改就怎麼改。這其實是不符合設計模式的,對於業務的拓展不修改原來的程式碼,這就是AOP思想。 概念 AOP啥意

Spring 學習 Spring-AOP 核心概念

核心概念 術語 描述 方面/切面(Aspect) 一個具有一組API的模組,提供交叉要求。例如,日誌記錄模組被稱為AOP方面用於記錄。應用程式可以根據需要具有任意數量的方面。

Spring5.0原始碼學習系列Spring AOP簡述

## 前言介紹 附錄:[Spring原始碼學習專欄](https://blog.csdn.net/u014427391/category_10493299.html) 在前面章節的學習中,我們對Spring框架的IOC實現原始碼有了一定的瞭解,接著本文繼續學習Springframework一個核心的技術

Java動態代理學習Spring AOP基礎之一】

tor -1 我們 null exception 文件 cat static 一個   Spring AOP使用的其中一個底層技術就是Java的動態代理技術。Java的動態代理技術主要圍繞兩個類進行的    java.lang.reflect.InvocationHan

CgLib動態代理學習Spring AOP基礎之一】

div 目前 .get 不知道 ctu get() 內容 想要 外部依賴   如果不了解JDK中proxy動態代理機制的可以先查看上篇文章的內容:Java動態代理學習【Spring AOP基礎之一】   由於Java動態代理Proxy.newProxyInstance()的

Spring框架Spring AOP

權限 保持 eth before app spring win 應該 ctc 一、基於註解管理的AOP 1、Spring配置文件 <!-- 配置自動掃描包,自動掃描Bean組件,切面類 --> <context:component-scan

Java框架(六)Spring(AOP)

1.介紹 AOP為Aspect Oriented Programming的縮寫,意為:面向切面程式設計,通過預編譯方式和執行期動態代理實現程式功能的統一維護(增強方法)的一種技術。 AOP是OOP(面向物件程式設計)的延續,是軟體開發中的一個熱點,也是Spri

Spring學習Spring三種裝配機制:(二)顯示裝配bean

  今天我們介紹一下Spring三種裝配機制中的另外兩種裝配方式:JavaConfig和XML配置,這兩種方式區別於自動化裝配方式都屬於顯示裝配。 1、Java程式碼裝配bean 首先,我們通過在Config類中使用@Bean註解來宣告bean; @Bean註

JavaWeb 筆記 Spring AOP

Spring AOP AspectJ:Java 社群裡最完整最流行的 AOP 框架 在 Spring2.0 以上版本中, 可以使用基於 AspectJ 註解或基於 XML 配置的 AOP 基於 AspectJ 註解的 AOP 啟用 AspectJ 註解支援 引入

第65節:Java後端的學習Spring基礎

Java後端的學習之Spring基礎 如果要學習spring,那麼什麼是框架,spring又是什麼呢?學習spring中的ioc和bean,以及aop,IOC,Bean,AOP,(配置,註解,api)-springFramework. 各種學習的知識點: spring expressi

Java後端的學習Spring基礎

如果要學習spring,那麼什麼是框架,spring又是什麼呢?學習spring中的ioc和bean,以及aop,IOC,Bean,AOP,(配置,註解,api)-springFramework. 各種學習的知識點: spring expression languagesp

Java框架Spring AOP 面向切面 中的連線點與切點是什麼?

連線點 定義:連線點是一個應用執行過程中能夠插入一個切面的點。 連線點可以是呼叫方法時、丟擲異常時、甚至修改欄位時、 切面程式碼可以利用這些點插入到應用的正規流程中。使得程式執行過程中能夠應用通知的所有點。 切點 定義:如果通知定義了“什麼”和“何時”,那麼切點就定

Java框架Spring AOP 面向切面程式設計 有哪幾種實現方式?如何選擇適合的AOP實現方式?

文章目錄 1. 實現方式 2. JDK動態代理如何實現? 2.1 主要的實現過程 3. 如何選擇? 1. 實現方式 JDK 動態代理實現和 cglib 實現 2. JDK

Java框架Spring AOP (Aspect Oriented Programming) 面向切面程式設計是什麼?

Spring AOP是什麼? Spring AOP是面向切面程式設計,將功能程式碼從業務邏輯程式碼中分離出來。 它允許程式通過分離的應用業務邏輯與系統級別服務。 程式設計師只需專注自己的業務邏輯,而不需要管系統級服務。 容器中的物件能享有容器中的公共服務(日誌、安全)。

SSH框架學習Spring ---- 4、Spring的事務管理和jdbcTemplate

本節講的是spring對dao層的封裝,之前可能有更好的做法,但是要知道spring也提供了這種技術。 本節的主要內容是: 1、spring的jdbcTemplate操作(實現事務crud操作) 2、spring配置連線池 (1)配置c3p0連線池 (2)service和dao注

SSH框架學習Spring ---- 3、Spring封裝的監聽器和log4j的用法

第一部分:監聽器 問題所在: action呼叫service、service呼叫dao。每次訪問action的時候,都要建立一次物件,且載入一次配置檔案,這顯得很耗費資源。 底層解決方案 僅在伺服器啟動的時候,建立物件載入檔案,通過在底層使用監聽器、servletContex

SSH框架學習Spring ----1、Spring入門和IOC

一、 spring概述 開源的輕量級框架(不依賴很多其他東西–輕量級) 兩部分核心 aop 面向切面程式設計:擴充套件功能不是修改原始碼來實現 ioc 控制反轉:把物件的建立交給spring,通過配置代替之前的new物件操作。

Spring系列學習Spring Data Apache Hadoop資料訪問

英文原文:https://spring.io/projects/spring-hadoop 目錄 概述 介紹 特性 版本和分發支援 Spring Boot 配置 快速開始 學習 文件 示例 概述 注意:Spring for Apache Hadoo

Spring系列學習Spring Data Elasticsearch資料訪問

英文原文:https://spring.io/projects/spring-data-elasticsearch 目錄 概述 特性 快速開始 學習 文件 概述 Elasticsearch的Spring Data是Spring Data專案的一部分,該專案旨在為新