JAVA两种代理模式
2024-09-14 21:24:56
简单设计动态代理,基本模拟spring的动态代理方式。
before afterReturning around afterException after这些通知方法都可以这块模拟出来
spring的AOP:
1.在容器中的对象如果实现了接口则采用JDK的动态代理。
2在容器中的对象没有实现接口,则用(cglib)继承的方式实现动态代理。
现在模拟spring的动态代理。
首先准备接口(UserService)和实现接口的目标对象(UserServiceImpl)。
public interface UserService { void save(); }
public class UserServiceImpl implements UserService { public void save() {
System.out.println("保存用户");
} }
1.动态代理
/**
* 动态代理1
*
* @author shihaibin
* @param <T>
*
*/
public class UserServiceProxyFactory implements InvocationHandler { Object impl; public <T> Object getProxy(Class<T> clz) {
try {
impl = clz.newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 生成动态代理
Object usProxy = Proxy.newProxyInstance(clz.getClassLoader(), clz.getInterfaces(), this);
// 返回
return usProxy;
} /**
* 参数:1.当前代理對象 2.当前方法 3.当前方法执行的时候的参数
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
Object invoke = method.invoke(impl, args);
after();
return invoke;
}
//可以重写
public void before() {
System.out.println("之后");
} public void after() {
System.out.println("之后");
}
}
测试:
@Test
public void find1() {
// 简单的aop
UserServiceProxyFactory factory = new UserServiceProxyFactory();
UserService userServiceProxy = (UserService) factory.getProxy(UserServiceImpl.class);
userServiceProxy.save();
System.out.println(userServiceProxy instanceof UserServiceImpl);
}
2.cglib代理
/**
* 动态代理2 cglib代理
*
* @author shihaibin
*
*/
public class UserServiceProxyFactory2 implements MethodInterceptor { public <T> Object getProxy(Class<T> clz) {
Enhancer en = new Enhancer();// 帮我们生成代理对象
en.setSuperclass(clz);// 设置对谁进行代理
en.setCallback(this);//回调函数
return en.create();// 创建代理对象;
} /**
* prxoyobj:被代理的原始对象 method:被代理的原始方法 arg:运行期的参数 methodProxy:产生的代理方法
*/
public Object intercept(Object prxoyobj, Method method, Object[] arg, MethodProxy methodProxy) throws Throwable {
// 打开事务
System.out.println("打开事务!");
// 调用原有方法
Object invokeSuper = methodProxy.invokeSuper(prxoyobj, arg);
// 提交事务
System.out.println("提交事务!");
return invokeSuper;
}
}
测试:
@Test
public void find2() {
// 重写aop前后方法
UserServiceProxyFactory2 factoryContext = new UserServiceProxyFactory2();
UserService userServiceProxy = (UserService) factoryContext.getProxy(UserServiceImpl.class);
userServiceProxy.save();
// 判断代理对象是否属于被代理对象类型
// 代理对象继承了被代理对象=>true
System.out.println(userServiceProxy instanceof UserServiceImpl);// 判断是否属于被代理对象类型
}
最新文章
- Android学习笔记(十)
- 遗传算法的简单应用-巡回旅行商(TSP)问题的求解
- How to set colors of HTML tables
- 【Protle99SE】PCB中各层的含义【小汇】
- js之Math对象
- Oracle添加含有脏数据的约束
- IIS7二级域名添加同一证书
- 初学python之路-day10
- C#3.0 Lamdba表达式与表达式树
- [Go] golang连接redis测试
- 【Python全栈-JavaScript】jQuery效果
- Linux命令:source
- UVA12113-Overlapping Squares(二进制枚举)
- [hgoi#2019/2/24]玄学考试
- python 截取 取出一部分的字符串
- python之数据库内置方法以及pymysql的使用
- ubuntu18.10安装redis遇到问题
- TM1629A驱动程序
- 【C】——C语言字符串比较函数
- HDU2017新生赛 友好整数