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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring AOP解析

發(fā)布時間:2024/7/19 javascript 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring AOP解析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

AOP: Aspect Oriented Programming 面向切面編程。

AOP底層實現(xiàn)原理:代理模式

什么是代理模式?

通過代理控制對象的訪問,可以詳細訪問某個對象的方法,在這個方法調(diào)用處理,或調(diào)用后處理。既(AOP微實現(xiàn)) ,AOP核心技術(shù)面向切面編程。

代理模式分為靜態(tài)代理與動態(tài)代理

?

靜態(tài)代理:

什么是靜態(tài)代理?

由程序員創(chuàng)建或工具生成代理類的源碼,再編譯代理類。所謂靜態(tài)也就是在程序運行前就已經(jīng)存在代理類的字節(jié)碼文件,代理類和委托類的關(guān)系在運行前就確定了。

通過別的類B代理這個類A,這個類的具體情況,調(diào)用的類C并不知道

?

動態(tài)代理:

什么是動態(tài)代理?

1.代理對象,不需要實現(xiàn)接口

2.代理對象的生成,是利用JDK的API,動態(tài)的在內(nèi)存中構(gòu)建代理對象(需要我們指定創(chuàng)建代理對象/目標對象實現(xiàn)的接口的類型)

3.動態(tài)代理也叫做:JDK代理,接口代理

?

JDK動態(tài)代理:

實現(xiàn)方式:

1.通過實現(xiàn)InvocationHandler接口創(chuàng)建自己的調(diào)用處理器 IvocationHandler handler = new InvocationHandlerImpl(…);

2.通過為Proxy類指定ClassLoader對象和一組interface創(chuàng)建動態(tài)代理類Class clazz = Proxy.getProxyClass(classLoader,new Class[]{…});

3.通過反射機制獲取動態(tài)代理類的構(gòu)造函數(shù),其參數(shù)類型是調(diào)用處理器接口類型Constructor constructor = clazz.getConstructor(new Class[]{InvocationHandler.class});

4.通過構(gòu)造函數(shù)創(chuàng)建代理類實例,此時需將調(diào)用處理器對象作為參數(shù)被傳入Interface Proxy = (Interface)constructor.newInstance(new Object[] (handler));

需要被代理的類:

public interface Subject {public void rent();public void hello(String str); } public class RealSubject implements Subject {@Overridepublic void rent(){System.out.println("I want to rent my house");}@Overridepublic void hello(String str){System.out.println("hello: " + str);} }

動態(tài)代理類:

public class DynamicProxy implements InvocationHandler {// 這個就是我們要代理的真實對象private Object subject;// 構(gòu)造方法,給我們要代理的真實對象賦初值public DynamicProxy(Object subject){this.subject = subject;}@Overridepublic Object invoke(Object object, Method method, Object[] args)throws Throwable{// 在代理真實對象前我們可以添加一些自己的操作System.out.println("before rent house");System.out.println("Method:" + method);// 當代理對象調(diào)用真實對象的方法時,其會自動的跳轉(zhuǎn)到代理對象關(guān)聯(lián)的handler對象的invoke方法來進行調(diào)用method.invoke(subject, args);// 在代理真實對象后我們也可以添加一些自己的操作System.out.println("after rent house");return null;} }

調(diào)用:

public static void main(String[] args){// 我們要代理的真實對象Subject realSubject = new RealSubject();// 我們要代理哪個真實對象,就將該對象傳進去,最后是通過該真實對象來調(diào)用其方法的InvocationHandler handler = new DynamicProxy(realSubject);/** 通過Proxy的newProxyInstance方法來創(chuàng)建我們的代理對象,我們來看看其三個參數(shù)* 第一個參數(shù)handler.getClass().getClassLoader(),我們這里使用handler這個類的ClassLoader對象來加載我們的代理對象* 第二個參數(shù)realSubject.getClass().getInterfaces(),我們這里為代理對象提供的接口是真實對象所實行的接口,表示我要代理的是該真實對象,這樣我就能調(diào)用這組接口中的方法了* 第三個參數(shù)handler,我們這里將這個代理對象關(guān)聯(lián)到了上方的 InvocationHandler 這個對象上*/Subject subject = (Subject)Proxy.newProxyInstance(handler.getClass().getClassLoader(), realSubject.getClass().getInterfaces(), handler);System.out.println(subject.getClass().getName());subject.rent();subject.hello("world");}

結(jié)果:

$Proxy0before rent house Method:public abstract void com.xiaoluo.dynamicproxy.Subject.rent() I want to rent my house after rent housebefore rent house Method:public abstract void com.xiaoluo.dynamicproxy.Subject.hello(java.lang.String) hello: world after rent house

總結(jié):AOP主要是通過InvocationHandler(Interface)和 Proxy(Class)來實現(xiàn)

invoke是InvocationHandler的唯一方法

?

通過被代理的類,接口,以及我們實現(xiàn)的InvocationHandler作為參數(shù),調(diào)用newProxyInstance

這樣就把完成了代理

調(diào)用時通過invoke方法進行處理,我們可以在處理前后加上一些其他處理。

?

?

CGLIB動態(tài)代理:

public class CglibProxy implements MethodInterceptor {private Object targetObject;// 這里的目標類型為Object,則可以接受任意一種參數(shù)作為被代理類,實現(xiàn)了動態(tài)代理public Object getInstance(Object target) {// 設(shè)置需要創(chuàng)建子類的類this.targetObject = target;Enhancer enhancer = new Enhancer();enhancer.setSuperclass(target.getClass());enhancer.setCallback(this);return enhancer.create();} ?public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {System.out.println("開啟事物");Object result = proxy.invoke(targetObject, args);System.out.println("關(guān)閉事物");// 返回代理對象return result;}public static void main(String[] args) {CglibProxy cglibProxy = new CglibProxy();UserDao userDao = (UserDao) cglibProxy.getInstance(new UserDao());userDao.save();} }

java動態(tài)代理是利用反射機制生成一個實現(xiàn)代理接口的匿名類,在調(diào)用具體方法前調(diào)用InvokeHandler來處理。

而cglib動態(tài)代理是利用asm開源包,對代理對象類的class文件加載進來,通過修改其字節(jié)碼生成子類來處理。

?

編程中注解的AOP實現(xiàn):

@Component @Aspect public class AopLog { ?// 前置通知@Before("execution(* com.service.UserService.add(..))")public void begin() {System.out.println("前置通知");} ? ?// 后置通知@After("execution(* com.service.UserService.add(..))")public void commit() {System.out.println("后置通知");} ?// 運行通知@AfterReturning("execution(* com.service.UserService.add(..))")public void returning() {System.out.println("運行通知");} ?// 異常通知@AfterThrowing("execution(* com.service.UserService.add(..))")public void afterThrowing() {System.out.println("異常通知");} ?// 環(huán)繞通知@Around("execution(* com.service.UserService.add(..))")public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {System.out.println("環(huán)繞通知開始");proceedingJoinPoint.proceed();System.out.println("環(huán)繞通知結(jié)束");} }

?

總結(jié)

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

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