日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring AOP两种使用方式以及如何使用解析

發(fā)布時間:2025/3/11 javascript 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring AOP两种使用方式以及如何使用解析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

AOP是一種面向切面編程思想,也是面向?qū)ο笤O(shè)計(OOP)的一種延伸。

在Spring實現(xiàn)AOP有兩種實現(xiàn)方式,一種是采用JDK動態(tài)代理實現(xiàn),另外一種就是采用CGLIB代理實現(xiàn),Spring是如何實現(xiàn)的在上篇已經(jīng)講到了Spring Bean的生命周期以及IOC源碼解析

AOP可以做日志記錄,或者事務(wù)回滾,在Spring的事務(wù)使用就是通過AOP進行事務(wù)的回滾的

JDK動態(tài)代理

這個是屬于JDK提供的一種代理方式,需提供接口才能使用,主要用的類有兩個:1、Proxy:這個主要是生成接口代理對象;2、InvocationHandler:反射射包下的一個接口,Proxy生成的代理接口對象,調(diào)用接口方法就會走InvocationHandler實現(xiàn)類的invoke()?方法

?使用示例:

//創(chuàng)建一個接口 public class UserDao {String getUserInfo(); } //實現(xiàn)一個InvocationHandler接口的實現(xiàn)類 public class MyInvocationHandler implements InvocationHandler {//需實現(xiàn)的方法//proxy 代表當(dāng)前對象自己,建議不要使用,如果使用的話會反復(fù)的調(diào)用自己,而調(diào)用自己會反復(fù)走當(dāng)前invoke方法,容易出現(xiàn)棧溢出;//method 指調(diào)用的方法Method;//args 調(diào)用方法的參數(shù);@Overridepublic Object invoke(Object proxy, Method method, Object[] args){//....return null;}//獲取接口代理對象public <T> T getProxy(CLass<T> cls){//第一個參數(shù)為類加載器,這個可以默認(rèn)使用當(dāng)前的AppClassLoader,即使用getClassLoader()方法接口//需創(chuàng)建代理對象的接口class數(shù)組,//invocationHandler的實現(xiàn)類對象,這里調(diào)用的是當(dāng)前對象,調(diào)用的時候就會走當(dāng)前對象的invoke方法return (E) Proxy.newProxyInstance(cls.getClassLoader(), new Class<?>[] {cls},this);}}public static void main(Stirng[] args){UserDao dao = new MyInvocationHandler().getProxy(UserDao.class);//這樣就能獲取到了UserDao接口的代理對象了 }

在Spring當(dāng)中是采用?JdkDynamicAopProxy?這個類實現(xiàn)的,可以去源碼里看一下這個類繼承了InvocationHandler

CGLIB代理

這個代理就比較厲害了,是通過ASM修改 .class字節(jié)碼進行實現(xiàn)的,并且不需要接口,具體的組成結(jié)構(gòu)可以去看一下大佬寫的這篇CGLIB(Code Generation Library)

使用示例:

/*** CGLIB 代理*/Enhancer enhancer = new Enhancer();enhancer.setSuperclass(SpringTest06Service.class);enhancer.setCallback(new MethodInterceptor() {public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {System.out.println(Thread.currentThread().getName()+"run start...");Object result = arg3.invokeSuper(arg0, arg2);System.out.println(Thread.currentThread().getName()+"result:"+result);System.out.println(Thread.currentThread().getName()+"run end...");return result;}});service = (SpringTest06Service) enhancer.create();System.out.println(service);String testAop = service.testAop("aaaaaaaa", "bbbbbbbbbbb");System.out.println(testAop);

在Spring里面實現(xiàn)的類是?ObjenesisCglibAopProxy?

上面就是兩種代理的實現(xiàn)方式,但是在Spring里面是怎么使用的呢

Spring使用AOP

需引入Spring相關(guān)的AOP的包

<dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>5.1.12.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>5.1.12.RELEASE</version></dependency>

在配置類上需開啟AOP進行方法攔截,@EnableAspectJAutoProxy?啟動AOP代理,這個注解有兩個參數(shù)

1、proxyTargetClass:這個是指定使用JDK動態(tài)代理攔截(false)還是使用CGLIB進行攔截(true),默認(rèn)為false,

2、exposeProxy:表示是否能夠讓AopContext訪問,默認(rèn)為false就是不能訪問。

源碼是怎么解析可以自己去看,這個注解通過使用@Import注入了一個SmartInstantiationAwareBeanPostProcessor的實現(xiàn)類,可以自己調(diào)試查看,這里就不具體講了,有空就在聊聊吧

最后配置相對應(yīng)的切面攔截類

@Aspect @Component public class AopConfig {private static final Log log = LogFactory.getLog(AopConfig.class);//切點,需指定到具體修飾符,具體方法名以及具體參數(shù)類型,這里表示所有修飾符,com.test.SpringCoreTest.test06.service這個包下的所有類的所有方法并且參數(shù)為兩個的類型為String的方法進行攔截@Pointcut("execution(* com.test.SpringCoreTest.test06.service.*.*(String,String))")public void pointCut() {}//執(zhí)行前,位于Around環(huán)繞方法前的后面執(zhí)行@Before(value = "pointCut()")public void before() {System.out.println("方法執(zhí)行前 @Before ....");}//執(zhí)行后,位于Around環(huán)繞方法后的后面執(zhí)行@After(value = "pointCut()")public void after() {System.out.println("方法執(zhí)行后 @After ....");}//即將返回執(zhí)行@AfterReturning(value = "pointCut()")public void afterReturning() {System.out.println("方法執(zhí)行后返回 @AfterReturning ....");}//拋出異常執(zhí)行@AfterThrowing(value="pointCut()",throwing="e")public void afterThrowing(Exception e) {System.out.println("方法執(zhí)行異常后返回 @AfterThrowing ....");System.out.println(e);}//環(huán)繞方法,能夠攔截執(zhí)行參數(shù),并且能夠修改@Around(value = "pointCut()")public Object around(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("around方法執(zhí)行前@Around ....");Object obj = joinPoint.proceed();System.out.println("around方法執(zhí)行后@Around ....");return obj;}}

配置好后,調(diào)用攔截的方法就可以觸發(fā)AOP攔截了。

總結(jié)

以上是生活随笔為你收集整理的Spring AOP两种使用方式以及如何使用解析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。