應用的原型為 執行者:房屋中介Agency(分為JDKAgency、CGlibAgency) 被代理對象:程式員Programmer 被代理對象的實現介面:租戶Tenement(CGlibAgency時不需要實現介面) JDK動態代理:執行者 JDKAgency CGlib動態代理:執行者 CGli ...
應用的原型為
執行者:房屋中介Agency(分為JDKAgency、CGlibAgency)
被代理對象:程式員Programmer
被代理對象的實現介面:租戶Tenement(CGlibAgency時不需要實現介面)
Tenement 介面:
package com.suzao.spring.test; /** * Tenement * @Description 租戶 * @Param * @return * @Author mc * @Date 2018/12/28 16:44 */ public interface Tenement { /** * rentHouse * @Description 租房方法 * @Param [] * @return * @Author mc * @Date 2018/12/28 18:51 */ void rentHouse(); }
Programmer 實現類
package com.suzao.spring.test; /** * Programmer * @Description 程式員 * @Param * @return * @Author mc * @Date 2018/12/28 18:21 */ public class Programmer implements Tenement { /** * rentHouse * @Description 租房方法 * @Param [] * @return * @Author mc * @Date 2018/12/28 18:52 */ @Override public void rentHouse() { System.out.println("我是程式員,我在找房子!"); } }
JDK動態代理:執行者 JDKAgency
package com.suzao.spring.test; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * JDKAgency * @Description JDK房屋中介 * @Param * @return * @Author mc * @Date 2018/12/28 18:22 */ public class JDKAgency implements InvocationHandler{ //拿到被代理對象的引用 private Tenement target; public Object getTenementProxy(Tenement target){ this.target = target; Class clazz = target.getClass(); //clazz.getInterfaces() 獲取它的介面 //重新動態生成一個class位元組碼 //編譯 return Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(),this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("JDK房屋中介開始執行。。。"); System.out.println("----------------------------"); method.invoke(this.target,args); System.out.println("----------------------------"); System.out.println("JDK房屋中介結束執行。。。"); return null; } }
CGlib動態代理:執行者 CGlibAgency
package com.suzao.spring.test; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; import java.lang.reflect.Method; /** * CGlibAgency * @Description CGlib 租房中介 * @Param * @return * @Author mc * @Date 2018/12/28 19:11 */ public class CGlibAgency implements MethodInterceptor{ public Object getTenmentProxy(Class clazz){ Enhancer enhancer = new Enhancer(); //告訴cglib,生成的子類需要繼承那個類 enhancer.setSuperclass(clazz); //設置回調 enhancer.setCallback(this); //載入到jvm中,並返回代理對象 return enhancer.create(); } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { System.out.println("CGlib房屋中介開始執行。。。"); System.out.println("----------------------------"); methodProxy.invokeSuper(obj,args); System.out.println("----------------------------"); System.out.println("CGlib房屋中介結束執行。。。"); return null; } }
代理測試類 TestProxy
package com.suzao.spring.test; /** * TestProxy * @Description 測試代理 * @Param * @return * @Author mc * @Date 2018/12/28 18:46 */ public class TestProxy { public static void main(String[] args) { //java動態代理是利用反射機制生成一個實現被代理對象的介面的匿名類,在調用具體方法前調用InvokeHandler來處理。 //執行者 JDKAgency //被代理對象 Programmer //被代理對象實現的介面 Tenement Tenement tenement= (Tenement) new JDKAgency().getTenementProxy(new Programmer()); tenement.rentHouse(); System.out.println("\n\n"); //cglib動態代理利用asm開源包,對被代理對象類的class文件載入進來,通過修改其位元組碼生成子類來處理。 //執行者 CGlibAgency //被代理對象 Programmer Programmer programmer= (Programmer) new CGlibAgency().getTenmentProxy(new Programmer().getClass()); programmer.rentHouse(); } }
執行結果:
JDK房屋中介開始執行。。。 ---------------------------- 我是程式員,我在找房子! ---------------------------- JDK房屋中介結束執行。。。 CGlib房屋中介開始執行。。。 ---------------------------- 我是程式員,我在找房子! ---------------------------- CGlib房屋中介結束執行。。。
pom.xml中引用:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${org.springframework-version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${org.springframework-version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${org.springframework-version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${org.springframework-version}</version> </dependency>