代理模式

代理模式分类:

  静态模式:所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。

  动态模式:动态代理类的源码是在程序运行期间由JVM根据反射等机制动态的生成,所以不存在代理类的字节码文件。代理类和委托类的关系是在程序运行时确定。 

代理模式的特点:

  1.代理模式要求实现与被代理者相同的接口;

  2.代理必须要完成自己的本职工作;

  3.完成自己本职工作的同时 还要完成额外的操作;

代理的意义:

  在完成自己本职工作的同时,还要完成一些额外的操作。

静态代理模式(思想):

 1 //任务:控制事务   代理service层
 2 @Service("userService")      //实现接口的目的   让调用者在神不知鬼不觉的时候调用
 3 public class StaticProxy implements UserService{
 4 
 5     @Autowired
 6     private UserService target;
 7     
 8     @Autowired
 9     private TranactionManager tx;
10     
11     @Override
12     public void addUser() {
13         try {
14             tx.begin();  //事务开启
15             target.addUser();  //本职工作  调用目标对象完成操作
16             tx.commit();  //事务提交
17         } catch (Exception e) {
18             e.printStackTrace();
19             tx.rollback();
20         }
21         
22     }
23 
24     @Override
25     public void updateUser() {
26         try {
27             tx.begin();  //事务开启
28             target.updateUser();  //本职工作
29             tx.commit();  //事务提交
30         } catch (Exception e) {
31             e.printStackTrace();
32             tx.rollback();
33         }
34     }
35 }

优点:
  1.实现了业务层代码和事务层代码相分离

缺点:
  1.大量的代码重复
  2.静态代理这能代理一个类,做法不通用

 

动态代理模式:

1.JDK的动态代理:

  要求:要求被代理者的必须实现一个接口

实现一个动态代理:

 1 public class DynamicProxy {
 3     //获取代理对象
 4     public static Object getProxy(final Object target,final TranactionManager tx){
 5         Object proxy = 
 6                 Proxy.newProxyInstance(target.getClass().getClassLoader(), 
 7                 target.getClass().getInterfaces(), new InvocationHandler() {
 8                     
 9                     //代理对象调用方法时才会执行
10                     @Override
11                     public Object invoke(Object proxy, Method method, Object[] args)
12                             throws Throwable {
13                         tx.begin();
14                         Object result = method.invoke(target, args);  //调用真实对象的方法
15                         tx.commit();
16                         return result;
17                     }
18                 });
19         
20         return proxy;
21     }
22 }

优点:

  1.继承了静态代理的优点

  2.能够解决代码重复问题

  3.可以使用动态代理来处理一类业务

缺点:

  1.要求必须实现接口,否则不能生成代理对象

  2.如果指定方法较为麻烦.

2.CGlib的动态代理

  1.不管有无接口,都可以为其生成代理对象;

  2.生成的代理对象,是目标对象的子类;

CGLib动态代理实现:

 1 public class DynamicProxy {
 2     
 3     //获取代理对象
 4     public static Object getProxy(final Object target,final TranactionManager tx){
 5         
 6         //增强器   底层操作的是二进制码
 7         Enhancer enhancer = new Enhancer();
 8         
 9         //设置接口
10         enhancer.setInterfaces(target.getClass().getInterfaces());
11         
12         //设置父类
13         enhancer.setSuperclass(target.getClass());
14         
15         //设置回调
16         enhancer.setCallback(new MethodInterceptor() {    
17             @Override
18             public Object intercept(Object proxy, Method method, Object[] args,
19                     MethodProxy methodProxy) throws Throwable {
20                 
21                 tx.begin();
22                 //调用真实对象的方法
23                 Object result = method.invoke(target, args);
24                 tx.commit();
25                 
26                 return result;
27             }
28         });
29         
30         //创建代理对象
31         return enhancer.create();
32     }
33 }

CGLib代理对象的类型:class Servlet.webservlet$$EnhancerByCGLIB$$483da1e3

 

原文地址:https://www.cnblogs.com/tongxuping/p/7074219.html