這篇文章主要介紹“什么是Spring AOP”,在日常操作中,相信很多人在什么是Spring AOP問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”什么是Spring AOP”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
AOP是aspect-oriented programming的縮寫,譯為面向切面編程。利用 AOP 可以對業務邏輯的各個部分進行隔離,從而使得 業務邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發的效率。簡單來說,AOP就是不修改源代碼在主干功能里面添加新功能。
AOP底層使用了動態代理:在有接口的時候使用JDK 動態代理、在沒有接口的時候使用CGLIB字節碼動態代理。
簡介
使用JDK 動態代理需要用到JDK中的Proxy類里面的newProxyInstance方法創建代理對象。方法如下:
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h);
newProxyInstance方法的三個參數說明:
loader 定義代理類的類加載器
interfaces 代理類要實現的接口列表(可以多個)
h 指派方法調用的處理程序(要增強的功能在這里面實現)
newProxyInstance方法返回一個指定接口的代理類實例。
InvocationHandler接口中有個invoke方法,用于實現增強的功能:
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
invoke方法的三個參數說明:
proxy表示代理對象
method表示被增強的方法
args是方法的參數 若沒有則為null
示例代碼
代碼結構如下:
└─src
└─com
└─spring5
JDKProxy.java
UserDao.java
UserDaoImpl.java
UserDao接口:
public interface UserDao {
int add(int a,int b);
String update(String id);
}
UserDaoImpl類:
JDKProxy類:
運行結果:
方法之前執行…add :傳遞的參數…[1, 2]
I am add…
方法之后執行…com.spring5.UserDaoImpl@355da254
result:3
簡介
使用CGLIB字節碼動態代理不受代理類必須實現接口的限制,其底層采用ASM字節碼生成框架。CGLIB動態代理的優缺點:
使用字節碼技術生產代理類比JAVA反射效率高
不能對聲明為final的方法進行代理,因為其原理是動態生成被代理類的子類
需要實現接口MethodInterceptor,然后重寫intercept方法:
Object intercept(Object proxy, Method method, Object[] args, MethodProxy arg3) throws Throwable;
intercept方法的參數說明:
proxy CGLIB生成的代理類實例,也是目標對象的子類,相當于重寫父類方法
method 被代理方法
args 方法參數
為生成的代理類對方法的代理引用
intercept方法返回
另外用到了Enhancer類,它是Cglib中的一個字節碼增強器,先調它的setSuperclass()將被代理類設置成父類、再調setCallback函數執行intercept方法,最后調create()生成代理類。
示例代碼
代碼結構如下:
└─src
└─com
└─spring5
CglibProxy.java
User.java
User類:
public class User {
public void sleep() {
System.out.println("我想睡覺...");
}
}
CglibProxy類:
運行結果:
睡覺前脫衣服
我想睡覺…
起床穿衣服
概述
AOP相關的幾個術語:
連接點
類里面哪些方法可以被增強,這些方法稱為連接點
切入點
實際被真正增強的方法稱為切入點
通知
實際增強的邏輯部分稱為通知,分為前置通知、后置通知、環繞通知、異常通知和最終通知五種類型,其中最終通知相當于JAVA的finally。
切面
把通知應用到切入點過程
AspectJ不是 Spring 組成部分,是一個獨立的AOP 框架,一般把 AspectJ 和 Spirng 框架一起使 用,進行 AOP操作。增強就是代理的意思。
準備工作
在進行AOP操作的時候需要先引入下面四個Jar包
com.springsource.net.sf.cglib-2.2.0.jar
com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
spring-aspects-5.2.6.RELEASE.jar
引入包后的所有包如下:
com.springsource.net.sf.cglib-2.2.0.jar
com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
spring-aspects-5.2.6.RELEASE.jar
commons-logging-1.1.1.jar
spring-aop-5.2.6.RELEASE.jar
spring-beans-5.2.6.RELEASE.jar
spring-context-5.2.6.RELEASE.jar
spring-core-5.2.6.RELEASE.jar
spring-expression-5.2.6.RELEASE.jar
AspectJ的切入點表達式相關說明如下:
作用
知道對哪個類里面的哪個方法進行增強
語法
execution([權限修飾符] [返回類型] [類全路徑] [方法名稱]([參數列表]) )
示例
基于注解實現
主要步驟
主要步驟如下:
在spring 配置文件中,開啟注解掃描
需要在XML中引入context和aop的上下文空間。
使用注解創建 User 和 UserProxy 對象
在增強類上面添加注解 @Aspect
在 spring配置文件中開啟生成代理對象
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
開啟Aspectj生成對象后,會去代碼中掃描@aspect注解
配置不同類型的通知
在通知方法上面使用@Before、@AfterReturning、@Around、@AfterThrowing和@After注解,結合切入點表達式配置。
@after是在方法執行之后執行(有異常也執行),@afterReturning是在返回值之后執行(有異常不執行)。
示例代碼
代碼結構:
User類:
UserProxy類:
Test類:
無異常返回結果:
Around 環繞之前
前置通知 before
I am add
Around 環繞之后
最終通知 after
后置通知(返回通知)afterReturning
有異常時返回結果:
Around 環繞之前
前置通知 before
最終通知 after
異常通知 afterThrowing
java.lang.ArithmeticException: / by zero
相同切入點提取
用@Pointcut標簽
多個增強類對同一個方法進行增強
用@Order注解設置增強類優先級,數字類型值越小表示優先級越高。
@Component
@Aspect
@Order(1)
public class PersonProxy{ }
完全注解開發
在啟動配置類中添加@EnableAspectJAutoProxy注解:
@Configuration
@ComponentScan(basePackages = { "com.spring5"})
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class ConfigAop {
}
基于配置文件實現
具體步驟
創建增強類和被增強類,創建相關方法
在spring 配置文件中配置兩個類對象
在 spring 配置文件中配置AOP
示例代碼
代碼結構如下:
Student類:
StudentProxy類:
Test類:
bean.xml:
運行結果:
I am before…
I want to buy a book…
I am afterReturn…
到此,關于“什么是Spring AOP”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。