動态代理
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.符号
例如:
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>