java实现动态 代理方法浅析
作者:shichen2014 发布时间:2023-11-28 23:33:59
标签: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
感兴趣的读者可以实际测试一下本文实例,相信会有很大的收获。


猜你喜欢
- 页面拖动到最后一页 再向下滑动回复到 第一页,第一页向前滑动回到 最后一页同时,底部红色小圆点随着页面的滑动距离比例随时改变位置布局:<
- 安装Jenkins提示:首先Jenkins安装方式有2中,一种是yum安装,另一种是使用war的方式进行安装(war就需要安装tomcat)
- 初步计划:或许由于个人原因,排球计分系统在假期就完成了,一直未写博客,就这样一直在推就是不想写,在加上过完年就工作了,可能刚实习工作比较紧所
- 随着C语言的学习慢慢结束,博主也要开始学习一门新语言了,那就是java。所以博主将会开启一个新的关于java的专栏,所以想要慢慢和我一起学习
- 本文实例讲述了C#实现跨线程操作控件方法,分享给大家供大家参考。具体实现方法如下:由于在.net平台下Winform、wpf禁止跨线程直接访
- package com.robin;import java.io.File;import java.io.FileInputStream;i
- 前言本文主要给大家介绍了关于C#中foreach遍历的用法以及c#使用foreach需要知道的一些事,分享出来供大家参考学习,下面话不多说了
- springboot 统一设置时区控制springboot服务的时区为东八区@SpringBootApplicationpublic cla
- 作为一个ORM框架,hibernate肯定也需要满足我们实现表与表之间进行关联的需要。hibernate在关联方法的实现很简单。下面我们先来
- route_generator是什么这是一个简单的 Flutter 路由生成库,只需要少量的代码,然后利用注解配合源代码生成,自动生成路由表
- 一、@RequestMapping注解的功能从注解名称上我们可以看到,@RequestMapping注解的作用就是将请求和处理请求的控制器方
- 本文主要介绍的是通过使用java的相关类可以实现对文件或文件夹的压缩。zlib是一种数据压缩程序库,它的设计目标是处理单纯的数据(而不管数据
- package com.cooly;import java.util.LinkedList;/*** @author coolyqq*模拟打
- 创建类第一步新建一个java类QSV,构造函数传入需要解析的文件名称。public class QSV {private RandomAcc
- 本文实例为大家分享了java实现三角形分形山脉的具体代码,供大家参考,具体内容如下三角形分形山脉原理原型图如图,这是三角形分形山脉的一个原型
- 本文实例讲述了C#实现的xml操作类,分享给大家供大家参考,具体如下:using System;using System.Data;usin
- 前言内存治理一直是每个开发者最关心的问题,我们在日常开发中会遇到各种各样的内存问题,比如OOM,内存泄露,内存抖动等等,这些问题都有以下共性
- 引言设计: 嗯? 这个图片点击跳转进详情再返回图片怎么变白闪一下呢?产品: 是啊是啊! 一定是个bug开发: 囧囧囧在开发过程中, 也许你也
- 本文实例讲述了C语言二叉树常见操作。分享给大家供大家参考,具体如下:一、基本概念每个结点最多有两棵子树,左子树和右子树,次序不可以颠倒。性质
- 当我们在登录像QQ邮箱这种大多数的网站,往往在登录按键上会有下次自动登录这个选项,勾选后登录成功,在一段时间内,即便退出浏览器或者服务器重启