您好,登錄后才能下訂單哦!
本篇內容介紹了“Spring中AOP概念與兩種動態代理模式原理是什么”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
AOP 為Aspect Oriented Programming 的縮寫,意思為面向切面編程,是通過預編譯方式和運行期動態代理實現程序功能的統一維護的一種技術。
AOP 是 OOP 的延續,是軟件開發中的一個熱點,也是Spring框架中的一個重要內容,是函數式編程的一種衍生范型。利用AOP可以對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發的效率。
作用:在程序運行期間,在不修改源碼的情況下對方法進行功能增強優勢:減少重復代碼,提高開發效率,并且便于維護
Spring 的 AOP 實現底層就是對上面的動態代理的代碼進行了封裝,封裝后我們只需要對需要關注的部分進行代碼編寫,并通過配置的方式完成指定目標的方法增強。在正式講解 AOP 的操作之前,我們必須理解 AOP 的相關術語,常用的術語如下:
Target(目標對象):代理的目標對象Proxy (代理):一個類被 AOP 織入增強后,就產生一個結果代理類Joinpoint(連接點):所謂連接點是指那些被攔截到的點。在spring中,這些點指的是方法,因為spring只支持方法類型的連接點.(可能被增強的方法)Pointcut(切入點):所謂切入點是指我們要對哪些 Joinpoint 進行攔截的定義(被增強的方法)Advice(通知/ 增強):所謂通知是指攔截到 Joinpoint 之后所要做的事情就是通知(對目標對象增強的方法)Aspect(切面):是切入點和通知(引介)的結合(目標方法+增強=切面)Weaving(織入):是指把增強應用到目標對象來創建新的代理對象的過程。 spring采用動態代理織入,而AspectJ采用編譯期織入和類裝載期織入.(一個動作,切點和通知結合的過程=織入)
需要編寫的內容 編寫核心業務代碼(目標類的目標方法)編寫切面類,切面類中有通知(增強功能方法)在配置文件中,配置織入關系,即將哪些通知與哪些連接點進行結合 AOP 技術實現的內容 Spring 框架監控切入點方法的執行。一旦監控到切入點方法被運行,使用代理機制,動態創建目標對象的代理對象,根據通知類別,在代理對象的對應位置,將通知對應的功能織入,完成完整的代碼邏輯運行。 AOP 底層使用哪種代理方式 在 spring 中,框架會根據目標類是否實現了接口來決定采用哪種動態代理的方式。
實際上, AOP 的底層是通過 Spring 提供的的動態代理技術實現的。在運行期間, Spring通過動態代理技術動態的生成代理對象,代理對象方法執行時進行增強功能的介入,在去調用目標對象的方法,從而完成功能的增強。
常用的動態代理技術
JDK 代理 : 基于接口的動態代理技術
cglib 代理:基于父類的動態代理技術
2.基于jdk的動態代理代碼
//---------接口1------------ package com.itspring.proxy.jdk; public interface TargetInterface1 { void save(); } //---------接口2------------ package com.itspring.proxy.jdk; public interface TargetInterface2 { void update(); } //---------接口1,接口2實現類(目標類)------------ package com.itspring.proxy.jdk; //目標類(被增強的類) public class Target implements TargetInterface1 ,TargetInterface2{ public void save() { System.out.println("save running..."); } public void update() { System.out.println("update running..."); } }
//---------通知類(方法增強類)------------ package com.itspring.proxy.jdk; //通知類(增強類) public class Advice { public void before() { System.out.println("前置增強..."); } public void afterRunning() { System.out.println("后置增強..."); } }
//---------測試代碼------------ package com.itspring.proxy.jdk; import org.junit.Test; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class ProxyTest { @Test public void test1() { final Target target = new Target(); final Advice advice = new Advice(); //返回值就是動態生成的代理對象 TargetInterface1 proxy1 = (TargetInterface1) Proxy.newProxyInstance( target.getClass().getClassLoader(), //目標類的類加載器 target.getClass().getInterfaces(), //目標類實現的接口(可能有多個) new InvocationHandler() { //調用代理對象的任何方法,實質上都是調用invoke方法 public Object invoke(Object proxy, //代理對象 Method method, //目標方法對象 Object[] args //目標方法的參數 ) throws Throwable { System.out.println("正在執行的方法:" + method.getName()); advice.before(); //前置增強 Object invoke = method.invoke(target, args); //執行目標方法 advice.afterRunning(); //后置增強 return invoke; } } ); proxy1.save(); //返回值就是動態生成的代理對象 TargetInterface2 proxy2 = (TargetInterface2) Proxy.newProxyInstance( target.getClass().getClassLoader(), //目標類的類加載器 target.getClass().getInterfaces(), //目標類實現的接口(可能有多個) new InvocationHandler() { //調用代理對象的任何方法,實質上都是調用invoke方法 public Object invoke(Object proxy, //代理對象 Method method, //目標方法對象 Object[] args //目標方法的參數 ) throws Throwable { System.out.println("正在執行的方法:" + method.getName()); advice.before(); Object invoke = method.invoke(target, args); //執行目標方法 advice.afterRunning(); return invoke; } } ); proxy2.update(); } }
cglib是第三方的庫,spring集成了cglib.
//---------目標類------------- package com.itspring.proxy.cglib; import com.itspring.proxy.jdk.TargetInterface1; import com.itspring.proxy.jdk.TargetInterface2; //目標類(被增強的類) public class Target { public void save() { System.out.println("save running..."); } public void update() { System.out.println("update running..."); } }
//---------通知類(增強類)------------- package com.itspring.proxy.cglib; //通知類(增強類) public class Advice { public void before() { System.out.println("前置增強..."); } public void afterRunning() { System.out.println("后置增強..."); } }
//---------測試代碼------------- package com.itspring.proxy.cglib; import com.itspring.proxy.jdk.TargetInterface1; import com.itspring.proxy.jdk.TargetInterface2; import org.junit.Test; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class ProxyTest { @Test public void test1() { //目標對象 final Target target = new Target(); //增強對象 final Advice advice = new Advice(); //基于cglib生成動態代理對象 //1.創建增強器 Enhancer enhancer = new Enhancer(); //2.創建父類 enhancer.setSuperclass(Target.class); //3.設置回調 enhancer.setCallback(new MethodInterceptor() { public Object intercept(Object proxy, //代理對象 Method method, //目標方法 Object[] objects, //目標方法的參數 MethodProxy methodProxy) //目標方法的代理 throws Throwable { //前置增強 advice.before(); //目標方法 Object invoke = method.invoke(target, objects); //后置增強 advice.afterRunning(); return invoke; } }); //4.生成代理對象 Target target1 = (Target) enhancer.create(); //5.測試 target1.save(); target1.update(); } }
“Spring中AOP概念與兩種動態代理模式原理是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。