1. 程式人生 > 其它 >Spring-xml實現AOP

Spring-xml實現AOP

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> 最終通知,無論是否有異常都執行