Spring-xml實現AOP
阿新 • • 發佈:2022-04-05
AOP相關概念
Spring的AOP實現底層就是對上面的動態代理進行了封裝。
- Target(代理物件):代理的目標物件
- Proxy(代理):一個類被AOP織入增強後,就產生一個結果代理類
- Joinpoint(連線點):被攔截到的點(方法),spring只支援方法型別的連線點
- Pointcut(切入點):指對哪些Joinpoint進行攔截的定義
- Advice(通知/增強):攔截Joinpoint之後要做的事
- Aspect(切面):切入點和通知的結合
- Weaving(織入):指把增強應用到目標物件來建立新的代理物件的過程
xml實現AOP
1. 匯入相關座標
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.3.17</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.9</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.3.17</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.2</version> <scope>test</scope> </dependency>
2. 建立目標介面和目標類(內部有切點)
package com.sjj.aop;
public interface TargetInterface {
public void print_hello();
}
package com.sjj.aop;
public class Target implements TargetInterface{
@Override
public void print_hello() {
System.out.println("HHHHHello");
}
}
3. 建立切面類(內部有增強方法)
package com.sjj.aop; public class MyAspect { public void before(){ System.out.println("=====前置增強====="); } }
4. 將目標類和切面類的物件建立權交給spring
<!--目標物件-->
<bean id="target" class="com.sjj.aop.Target"/>
<!--切面物件-->
<bean id="myAspect" class="com.sjj.aop.MyAspect"/>
5. 在appContext.xml中配置織入關係
<!--配置織入:增強方法--> <aop:config> <!--宣告切片--> <aop:aspect ref="myAspect"> <!--切點、通知--> <aop:before method="before" pointcut="execution(public void com.sjj.aop.Target.print_hello())" /> </aop:aspect> </aop:config>
6. 測試程式碼
package com.sjj.aop;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:appContext.xml")
public class AopTest {
@Autowired
private TargetInterface target;
@Test
public void test_aop01(){
target.print_hello();
}
}
配置解析
切點表示式
execution([修飾符] 返回值型別 包名.類名.方法名(引數))
- 訪問修飾符可省略
- 返回值型別、包名、類名、方法名可用 * 表示任意
- 包名和類之間的 . 表示當前包下的類。兩個點 .. 表示包及其子包下的類
- 引數列表可以使用 .. 表示任意個數任意型別的引數
所以你甚至可以這麼寫(bushi
execution(* *..*.*(..))
通知
<aop:通知型別 method="切面類中的方法名" pointcut="切點表示式"></aop:通知型別>
名稱 | 標籤 | 說明 |
---|---|---|
前置 | <aop:before> | 切入點方法之前 |
後置 | <aop:after-returning> | 切入點方法之後 |
環繞 | <aop:around> | 切入點方法前後都執行 |
異常丟擲 | <aop:throwing> | 出現異常時執行 |
最終 | <aop:after> | 最終通知,無論是否有異常都執行 |