1. 程式人生 > 其它 >【spring AOP】AspectJProxyFactory

【spring AOP】AspectJProxyFactory

AspectJProxyFactory,可能大家對這個比較陌生,但是@Aspect這個註解大家應該很熟悉吧,通過這個註解在spring環境中實現aop特別的方便。

而AspectJProxyFactory這個類可以通過解析@Aspect標註的類來生成代理aop代理物件,對開發者來說,使建立代理變的更簡潔了。

先了解幾個概念

文中會涉及幾個概念,先了解一下。

target

用來表示目標物件,即需要通過aop來增強的物件。

proxy

代理物件,target通過aop增強之後生成的代理物件。

AspectJ是什麼?

AspectJ是一個面向切面的框架,是目前最好用,最方便的AOP框架,和spring中的aop可以整合在一起使用,通過Aspectj提供的一些功能實現aop代理變得非常方便。

AspectJ使用步驟

1.建立一個類,使用@Aspect標註

2.@Aspect標註的類中,通過@Pointcut定義切入點

3.@Aspect標註的類中,通過AspectJ提供的一些通知相關的註解定義通知

4.使用AspectJProxyFactory結合@Ascpect標註的類,來生成代理物件

案例

來個類

package com.javacode2018.aop.demo9.test1;

public class Service1 {

    public void m1() {
        System.out.println("我是 m1 方法");
    }

    public void m2() {
        System.out.println(10 / 0);
        System.out.println("我是 m2 方法");
    }
}

通過AspectJ來對Service1進行增強,來2個通知,一個前置通知,一個異常通知,這2個通知需要對Service1中的所有方法生效,實現如下:

package com.javacode2018.aop.demo9.test1;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

//@1:這個類需要使用@Aspect進行標註
@Aspect
public class Aspect1 {

    //@2:定義了一個切入點,可以匹配Service1中所有方法
    @Pointcut("execution(* com.javacode2018.aop.demo9.test1.Service1.*(..))")
    public void pointcut1() {
    }

    //@3:定義了一個前置通知,這個通知對剛剛上面我們定義的切入點中的所有方法有效
    @Before(value = "pointcut1()")
    public void before(JoinPoint joinPoint) {
        //輸出連線點的資訊
        System.out.println("前置通知," + joinPoint);
    }

    //@4:定義了一個異常通知,這個通知對剛剛上面我們定義的切入點中的所有方法有效
    @AfterThrowing(value = "pointcut1()", throwing = "e")
    public void afterThrowing(JoinPoint joinPoint, Exception e) {
        //發生異常之後輸出異常資訊
        System.out.println(joinPoint + ",發生異常:" + e.getMessage());
    }

}

@1:類上使用@Aspect標註

@2:通過@Pointcut註解標註在方法上面,用來定義切入點

@3:使用@Before標註在方法上面,定義了一個前置通知,通過value引用了上面已經定義的切入點,表示這個通知會對Service1中的所有方法生效,在通知中可以通過這個類名.方法名()引用@Pointcut定義的切入點,表示這個通知對這些切入點有效,若@Before和@Pointcut在一個類的時候,直接通過方法名()引用當前類中定義的切入點

@4:這個使用@AfterThrowing定義了一個異常通知,也是對通過value引用了上面已經定義的切入點,表示這個通知會對Service1中的所有方法生效,若Service1中的方法丟擲了Exception型別的異常,都會回撥afterThrowing方法。

來個測試類

package com.javacode2018.aop.demo9;

import com.javacode2018.aop.demo9.test1.Aspect1;
import com.javacode2018.aop.demo9.test1.Service1;
import org.junit.Test;
import org.springframework.aop.aspectj.annotation.AspectJProxyFactory;

public class AopTest9 {
    @Test
    public void test1() {
        try {
            //對應目標物件
            Service1 target = new Service1();
            //建立AspectJProxyFactory物件
            AspectJProxyFactory proxyFactory = new AspectJProxyFactory();
            //設定被代理的目標物件
            proxyFactory.setTarget(target);
            //設定標註了@Aspect註解的類
            proxyFactory.addAspect(Aspect1.class);
            //生成代理物件
            Service1 proxy = proxyFactory.getProxy();
            //使用代理物件
            proxy.m1();
            proxy.m2();
        } catch (Exception e) {
        }
    }
}

執行輸出

前置通知,execution(void com.javacode2018.aop.demo9.test1.Service1.m1())
我是 m1 方法
前置通知,execution(void com.javacode2018.aop.demo9.test1.Service1.m2())
execution(void com.javacode2018.aop.demo9.test1.Service1.m2()),發生異常:/ by zero

AspectJProxyFactory原理

@Aspect標註的類上,這個類中,可以通過通過@Pointcut來定義切入點,可以通過@Before@Around@After@AfterRunning@AfterThrowing標註在方法上來定義通知,定義好了之後,將@Aspect標註的這個類交給AspectJProxyFactory來解析生成Advisor鏈,進而結合目標物件一起來生成代理物件,大家可以去看一下原始碼,比較簡單,這裡就不多解釋了。