java实现动态代理方法浅析
一些java项目中在mybatis与spring整合中有mapperscannerconfigurer的使用,该类通过反向代理自动生成基于接口的动态代理类。
有鉴于此,本文浅析了java的动态代理。
本文使用动态代理模拟处理事务的拦截器。
接口:
public interface userservice { public void adduser(); public void removeuser(); public void searchuser(); }
实现类:
public class userserviceimpl implements userservice { public void adduser() { system.out.println("add user"); } public void removeuser() { system.out.println("remove user"); } public void searchuser() { system.out.println("search user"); } }
java动态代理的实现有2种方式
1.jdk自带的动态代理
使用jdk自带的动态代理需要了解invocationhandler接口和proxy类,他们都是在java.lang.reflect包下。
invocationhandler介绍:
invocationhandler是代理实例的调用处理程序实现的接口。
每个代理实例都具有一个关联的invocationhandler。对代理实例调用方法时,这个方法会调用invocationhandler的invoke方法。
proxy介绍:
proxy 提供静态方法用于创建动态代理类和实例。
实例(模拟aop处理事务):
public class transactioninterceptor implements invocationhandler { private object target; public void settarget(object target) { this.target = target; } @override public object invoke(object proxy, method method, object[] args) throws throwable { system.out.println("start transaction"); method.invoke(target, args); system.out.println("end transaction"); return null; } }
测试代码:
public class testdynamicproxy { @test public void testjdk() { transactioninterceptor transactioninterceptor = new transactioninterceptor(); userservice userservice = new userserviceimpl(); transactioninterceptor.settarget(userservice); userservice userserviceproxy = (userservice) proxy.newproxyinstance( userservice.getclass().getclassloader(), userservice.getclass().getinterfaces(), transactioninterceptor); userserviceproxy.adduser(); } }
测试结果:
start transaction add user end transaction
很明显,我们通过userserviceproxy这个代理类进行方法调用的时候,会在方法调用前后进行事务的开启和关闭。
2. 第三方库cglib
cglib是一个功能强大的,高性能、高质量的代码生成库,用于在运行期扩展java类和实现java接口。
它与jdk的动态代理的之间最大的区别就是:
jdk动态代理是针对接口的,而cglib是针对类来实现代理的,cglib的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。
实例代码如下:
public class userservicecallback implements methodinterceptor { @override public object intercept(object o, method method, object[] args, methodproxy methodproxy) throws throwable { system.out.println("start transaction by cglib"); methodproxy.invokesuper(o, args); system.out.println("end transaction by cglib"); return null; } }
测试代码:
public class testdynamicproxy { @test public void testcglib() { enhancer enhancer = new enhancer(); enhancer.setsuperclass(userserviceimpl.class); enhancer.setcallback(new userservicecallback()); userserviceimpl proxy = (userserviceimpl)enhancer.create(); proxy.adduser(); } }
测试结果:
start transaction by cglib add user end transaction by cglib
感兴趣的读者可以实际测试一下本文实例,相信会有很大的收获。
上一篇: 浅谈springboot多模块(modules)开发
下一篇: java LRU算法介绍与用法示例