JDK与CGlib动态代理的实现
Posted benefitworld
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDK与CGlib动态代理的实现相关的知识,希望对你有一定的参考价值。
应用的原型为
执行者:房屋中介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(" "); //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>
以上是关于JDK与CGlib动态代理的实现的主要内容,如果未能解决你的问题,请参考以下文章