BigDataKer 2019-05-23 08:30:00
Spring主要有兩大思想,一個是IOC,另一個就是AOP。對於Spring的核心AOP來說,AOP的原理就是java的動態代理機制來實現,所以本篇主要對java動態代理做一個簡單介紹.
1、代理(Dynamic Proxy)
代理分爲靜態代理和動態代理,靜態代理是在編譯時就將接口、實現類、代理類一股腦兒全部手動完成,但如果我們需要很多的代理,每一個都這麼手動的去創建實屬浪費時間,而且會有大量的重複代碼,此時我們就可以採用動態代理。動態代理可以在程序運行期間根據需要動態的創建代理類及其實例,來完成具體的功能。
其實方法直接調用就可以完成功能,爲什麼還要加個代理呢?
原因是採用代理模式可以有效的將具體的實現與調用方進行解耦,通過面向接口進行編碼完全將具體的實現隱藏在內部。
2、代理實現的一般模式
其實代理的一般模式就是靜態代理的實現模式:首先創建一個接口(JDK代理都是面向接口的),然後創建具體實現類來實現這個接口;再創建一個代理類同樣實現這個接口。不同之處在於,具體實現類的方法中需要將接口中定義的方法的業務邏輯功能實現,而代理類中的方法只要調用具體類中的對應方法即可。這樣我們在需要使用接口中的某個方法的功能時直接調用代理類的方法即可,將具體的實現類隱藏在底層。
一般而言,動態代理分爲兩種,一種是JDK反射機制提供的代理,另一種是CGLIB代理。在JDK代理,必須提供接口,而CGLIB則不需要提供接口,在Mybatis裏兩種動態代理技術都已經使用了,在Mybatis中通常在延遲加載的時候纔會用到CGLIB動態代理。
1.JDK動態代理:
public interface Rent { public void rent(); }
public class Landlord implements Rent{ @Override public void rent() { System.out.println("房東要出租房子了!"); } }
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class Intermediary implements InvocationHandler{ private Object post; Intermediary(Object post){ this.post = post; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object invoke = method.invoke(post, args); System.out.println("中介:該房源已發佈!"); return invoke; } }
import java.lang.reflect.Proxy; public class Test { public static void main(String[] args) { Rent rent = new Landlord(); Intermediary intermediary = new Intermediary(rent); Rent rentProxy = (Rent) Proxy.newProxyInstance(rent.getClass().getClassLoader(), rent.getClass().getInterfaces(), intermediary); rentProxy.rent(); } }
2.CGLIB動態代理:
public class Landlord { public void rent(){ System.out.println("房東要出租房子了!"); } }
import java.lang.reflect.Method; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class Intermediary implements MethodInterceptor { @Override public Object intercept(Object object, Method method, Object[] args,MethodProxy methodProxy) throws Throwable { Object intercept = methodProxy.invokeSuper(object, args); System.out.println("中介:該房源已發佈!"); return intercept; } }
import net.sf.cglib.proxy.Enhancer; public class Test { public static void main(String[] args) { Intermediary intermediary = new Intermediary(); Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(Landlord.class); enhancer.setCallback(intermediary); Landlord rentProxy = (Landlord) enhancer.create(); rentProxy.rent(); } }
本文轉載於博客園如果屈原會編程的博客