天天看點

關于spring架構的核心技術之Aop

動态代理

spring架構的aop技術實作其實就是基于動态代理。

  • 動态代理的含義

    程式在執行過程中自動生成代理對象,通過代理對象的執行方法,使得被代理對象源代碼不更改的情況下實作其功能擴充。

  • jdk動态代理

    jdk内置的動态代理要求代理對象要實作接口,jdk提供了三個類,Proxy、Method、InvocationHandler用于建立代理對象,實作功能擴充。

  • cglib 動态代理

    cglib是第三方類庫,要求被代理類必須可以被繼承,其子類就是功能增強了的代理對象,要求被代理類及其方法不能被final修飾。

AOP

Aop:面向切面程式設計,切面就是我們需要增加的功能,也是一種思想,是基于jdk,cglib動态代理的,是動态代理的規範化。

  • 要點

    1.使用時先找到被代理對象的切面,也就是除了業務之外的功能。

    2.确定切面執行的時間

    3.确定切面的執行位置,給誰增強功能

  • AOP的技術實作架構

    使用aspectJ架構,在maven項目pom.xml中添加依賴包

    1.切面執行時間常用使用以下的注解

    @Before

    @AfterReturning

    @Around

    @AfterThrowing

    @After

    2.切面的執行位置采用切入點表達式

    以上幾個注解均有屬性value,屬性值為切入點表示式的字元串,表示切面執行的位置

    文法格式:

    execution(通路權限 方法傳回值 方法聲明(參數) 異常類型)

    3.符号

    關于spring架構的核心技術之Aop

    例如:

    execution(public * *(…)) //指定切入點為:任意公共方法。

代碼

  • 接口
//接口
public interface Target {
    void doSome(String name,Integer age);
}
           
  • 實作類
/**
 - 被代理對象
 */
public class TargetImpl implements Target {
    @Override
    public void doSome(String name,Integer age) {
        //在執行doSome方法前增加一個功能
        System.out.println("targetImpl的doSome方法執行了");
    }
}
           
  • 切面類
//@Aspect注解聲明這個類是切面類
@Aspect
public class ProxyByAspectJ {
    /**
     * 聲明需要增加的功能
     * 注意:
     * 1.這個功能需是public修飾
     * 2.這個功能沒有傳回值
     */
    //Before:前置通知注解,在被代理對象方法執行之前執行
    //execution(public * *.doSome(..)):任意包中的doSome方法,可以寫具體切入點表示式
    @Before(value="execution(public * *.doSome(..))")
    public void doBefore(){
        System.out.println("在doSome方法之前執行這個功能");
    }
}
           
  • 在xml配置檔案中聲明aspectj架構中的自動代理生成器标簽
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--建立被代理對象-->
    <bean id="target" class="com.huangliutan.TargetImpl"/>

    <!--建立切面類對象-->
    <bean id="proxy" class="com.huangliutan.ProxyByAspectJ"/>

    <!--聲明自動生成代理生成器,在記憶體中改變被代理對象的結構為代理對象-->
    <context:aspectj-autoproxy/>
</beans>