欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JAVA两种代理模式

程序员文章站 2022-06-21 16:07:24
简单设计动态代理,基本模拟spring的动态代理方式。 before afterReturning around afterException after这些通知方法都可以这块模拟出来 spring的AOP: 1.在容器中的对象如果实现了接口则采用JDK的动态代理。 2在容器中的对象没有实现接口,则 ......

简单设计动态代理,基本模拟spring的动态代理方式。

before afterReturning around afterException after这些通知方法都可以这块模拟出来

spring的AOP: 

1.在容器中的对象如果实现了接口则采用JDK的动态代理。

2在容器中的对象没有实现接口,则用(cglib)继承的方式实现动态代理。

现在模拟spring的动态代理。

首先准备接口(UserService)和实现接口的目标对象(UserServiceImpl)。

 

1 public interface UserService {
2 
3 void save(); 
4 
5 }
1 public class UserServiceImpl implements UserService {
2 
3     public void save() {
4         System.out.println("保存用户");
5     } 
6 
7 }

 

1.动态代理

 1 /**
 2  * 动态代理1
 3  * 
 4  * @author shihaibin
 5  * @param <T>
 6  *
 7  */
 8 public class UserServiceProxyFactory implements InvocationHandler {
 9 
10     Object impl;
11 
12     public <T> Object getProxy(Class<T> clz) {
13         try {
14             impl = clz.newInstance();
15         } catch (InstantiationException e) {
16             // TODO Auto-generated catch block
17             e.printStackTrace();
18         } catch (IllegalAccessException e) {
19             // TODO Auto-generated catch block
20             e.printStackTrace();
21         }
22         // 生成动态代理
23         Object usProxy = Proxy.newProxyInstance(clz.getClassLoader(), clz.getInterfaces(), this);
24         // 返回
25         return usProxy;
26     }
27 
28     /**
29      * 参数:1.当前代理對象 2.当前方法 3.当前方法执行的时候的参数
30      */
31     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
32         before();
33         Object invoke = method.invoke(impl, args);
34         after();
35         return invoke;
36     }
37     //可以重写
38     public void before() {
39         System.out.println("之后");
40     }
41 
42     public void after() {
43         System.out.println("之后");
44     }
45 }

测试:

1 @Test
2     public void find1() {
3         // 简单的aop
4         UserServiceProxyFactory factory = new UserServiceProxyFactory();
5         UserService userServiceProxy = (UserService) factory.getProxy(UserServiceImpl.class);
6         userServiceProxy.save(); 
7         System.out.println(userServiceProxy instanceof UserServiceImpl);
8     }

 

2.cglib代理

 1 /**
 2  * 动态代理2 cglib代理
 3  * 
 4  * @author shihaibin
 5  *
 6  */
 7 public class UserServiceProxyFactory2 implements MethodInterceptor {
 8 
 9     public <T> Object getProxy(Class<T> clz) {
10         Enhancer en = new Enhancer();// 帮我们生成代理对象
11         en.setSuperclass(clz);// 设置对谁进行代理
12         en.setCallback(this);//回调函数
13         return en.create();// 创建代理对象;
14     }
15 
16     /**
17      * prxoyobj:被代理的原始对象 method:被代理的原始方法 arg:运行期的参数 methodProxy:产生的代理方法
18      */
19     public Object intercept(Object prxoyobj, Method method, Object[] arg, MethodProxy methodProxy) throws Throwable {
20         // 打开事务
21         System.out.println("打开事务!");
22         // 调用原有方法
23         Object invokeSuper = methodProxy.invokeSuper(prxoyobj, arg);
24         // 提交事务
25         System.out.println("提交事务!");
26         return invokeSuper;
27     }
28 }

 

测试:

 1 @Test
 2     public void find2() {
 3         // 重写aop前后方法
 4         UserServiceProxyFactory2 factoryContext = new UserServiceProxyFactory2();
 5         UserService userServiceProxy = (UserService) factoryContext.getProxy(UserServiceImpl.class);
 6         userServiceProxy.save();
 7         // 判断代理对象是否属于被代理对象类型
 8         // 代理对象继承了被代理对象=>true
 9         System.out.println(userServiceProxy instanceof UserServiceImpl);// 判断是否属于被代理对象类型
10     }