Spring AOP實現原理
阿新 • • 發佈:2020-10-12
AOP實現原理:
編織: 靜態編織 通過修改原始碼或位元組碼在編譯器、後編譯器或載入器嵌入程式碼 動態編織 通過代理等技術在執行期實現嵌入。【AspectJ,Spring】 AOP是什麼? AOP(Aspect Orient Programming),我們一般稱為面向方面(切面)程式設計,作為面向物件的一種補充,用於處理系統中分佈於各個模組的橫切關注點,比如事務管理、日誌、快取等等。AOP實現的關鍵在於AOP框架自動建立的AOP代理,AOP代理主要分為靜態代理和動態代理,靜態代理的代表為AspectJ;而動態代理則以Spring AOP為代表。本文會分別對AspectJ和Spring AOP的實現進行分析和介紹。 Spring AOP如何實現的? Spring AOP中的動態代理主要有兩種方式,JDK動態代理和CGLIB動態代理。JDK動態代理通過反射來接收被代理的類,並且要求被代理的類必須實現一個介面。JDK動態代理的核心是InvocationHandler介面和Proxy類。 如果目標類沒有實現介面,那麼Spring AOP會選擇使用CGLIB來動態代理目標類。CGLIB(Code Generation Library),是一個程式碼生成的類庫,可以在執行時動態的生成某個類的子類,注意,CGLIB是通過繼承的方式做的動態代理,因此如果某個類被標記為final,那麼它是無法使用CGLIB做動態代理的。 JDK動態代理 package com.zb.zbook.z_springaop; public interface Service { /**add方法*/ void add(); /**update方法*/ void update(); } package com.zb.zbook.z_springaop; public class ServiceImpl implements Service{ @Override public void add() { System.out.println("AService add >>>>>>>>>"); } @Override public void update() { System.out.println("AService update >>>>>>>>>"); } } 實現動態代理類MyInvocationHandler,實現InvocationHandler介面,並且實現介面中的invoke方法。仔細看invoke方法,就是在該方法中加入切面邏輯的。目標類方法的執行是由mehod.invoke(target,args)這條語句完成。 package com.zb.zbook.z_springaop; import org.springframework.cglib.proxy.InvocationHandler; import java.lang.reflect.Method; public class MyInvocationHandler implements InvocationHandler { private Object target; public MyInvocationHandler(Object object){ super(); this.target = object; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("=========before========="); //程式執行 Object result = method.invoke(target, args); //程式執行後加入邏輯,MethodAfterAdviceInterceptor System.out.println("=========after=========="); return result; } } 測試類,其中增強的目標物件是由Proxy.newProxyInstance(aService.getClass().getClassLoader(),aService.getClass().getInterfaces(), handler);來生成的。 package com.zb.zbook.z_springaop; import org.springframework.cglib.proxy.InvocationHandler; import java.lang.reflect.Method; public class MyInvocationHandler implements InvocationHandler { private Object target; public MyInvocationHandler(Object object){ super(); this.target = object; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("=========before========="); //程式執行 Object result = method.invoke(target, args); //程式執行後加入邏輯,MethodAfterAdviceInterceptor System.out.println("=========after=========="); return result; } }