java实现动态 代理方法浅析
作者:shichen2014 时间:2023-11-28 23:33:59
一些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
感兴趣的读者可以实际测试一下本文实例,相信会有很大的收获。
标签:java,动态,代理
0
投稿
猜你喜欢
mybatis中的count()按条件查询方式
2022-06-30 06:04:29
SpringCloud项目中Feign组件添加请求头所遇到的坑及解决
2023-04-28 03:46:58
Android基于Intent实现Activity之间数据传递的方法
2022-08-01 16:34:04
android 简单图片动画播放的实例代码
2023-11-07 12:39:01
unity 如何使用LineRenderer 动态划线
2021-10-27 03:42:50
android自定义ImageView仿图片上传示例
2023-08-11 20:34:08
Java中transient关键字的详细总结
2021-12-11 03:19:33
Android返回键功能的实现方法
2021-10-01 12:54:53
Android图片加载缓存框架Glide
2021-11-13 12:43:02
关于Tomcat出现The origin server did not find a current representation for the target resourc...的问题
2023-03-03 18:02:43
Java消息队列JMS实现原理解析
2023-05-14 04:02:04
Java常见数据结构面试题(带答案)
2023-11-24 19:44:05
Java实现JDK动态代理的原理详解
2021-09-19 08:17:43
java验证电话号码的方法
2023-04-01 21:44:41
Spring Bean自动装配入门到精通
2023-11-03 07:29:09
详细解读Java Spring AOP
2022-10-09 11:06:06
IntelliJ IDEA2019实现Web项目创建示例
2023-06-05 00:29:33
C#逐行读取文件的方法
2023-05-16 23:53:02
android实现倒计时功能代码
2022-06-28 03:57:31
c语言实现基数排序解析及代码示例
2021-10-17 19:37:51