spring-6、动态代理(cglib 与 JDK)

JDK动态代理与Cglib动态代理

 

JDK动态代理:

1.能够继承静态代理的全部优点.并且能够实现代码的复用.
2.动态代理可以处理一类业务.只要满足条件 都可以通过代理对象进行处
理.
3.动态代理的灵活性不强.
4.JDK 的动态代理要求代理者必须实现接口, , 否则不能生成代理对象. .

复制代码
 1 package proxy;
 2 
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Method;
 5 import java.lang.reflect.Proxy;
 6 
 7 import service.UserService;
 8 import tx.TransactionManager;
 9 
10 public class DynamicProxy {
11     
12     //创建代理对象   需要传入真实对象和事务对象
13     public static Object getProxy(final UserService target,final TransactionManager tx){
14         /**
15          * loader 真实对象的类加载器
16          * interfaces 真实对象的接口
17          * h 
18          * 问题:是否能够不传接口??   必须要求传入接口
19          */
20         Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(),
21                 target.getClass().getInterfaces(), 
22                 new InvocationHandler() {
23                     
24                     //当代理对象调用方法时才会执行invoke操作
25                     @Override
26                     public Object invoke(Object proxy, Method method, Object[] args)
27                             throws Throwable {
28                 
29                         tx.begin(); //事务开始
30                         Object result = method.invoke(target, args);//调用目标方法
31                         tx.commit();
32                         return result;
33                     }
34                 }
35                 );
36         
37         return proxy;
38     }
39 }
复制代码

-------------------------------------------------------------------------------

Cglib动态代理:

1.不管有无接口都可以创建代理对象.
2.cglib创建的代理对象是目标对象的子类.

复制代码
 1 package proxy;
 2 
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Method;
 5 import java.lang.reflect.Proxy;
 6 
 7 import org.springframework.cglib.proxy.Enhancer;
 8 import org.springframework.cglib.proxy.MethodInterceptor;
 9 import org.springframework.cglib.proxy.MethodProxy;
10 
11 import service.UserService;
12 import tx.TransactionManager;
13 
14 public class DynamicProxy {
15     
16     //创建代理对象   需要传入真实对象和事务对象
17     public static Object getProxy(final UserService target,final TransactionManager tx){
18         
19         //1.创建增强器    底层实现是通过二进制码的方式
20         Enhancer enhancer = new Enhancer();
21         
22         //2.设置接口
23         enhancer.setInterfaces(target.getClass().getInterfaces());
24         
25         //3.设置父类  cgLib创建的代理对象都是目标对象的子类
26         enhancer.setSuperclass(target.getClass());
27         
28         //4.设置回调
29         enhancer.setCallback(new MethodInterceptor() {
30             
31             @Override
32             public Object intercept(Object proxy, Method method, Object[] args,
33                     MethodProxy methodProxy) throws Throwable {
34                 
35                 tx.begin();
36                 //通过目标对象调用方法
37                 Object result = method.invoke(target, args);
38                 tx.commit();
39                 
40                 return result;
41             }
42         });
43         
44         //获取代理对象
45         return enhancer.create();
46     }
47 }
复制代码

另:

使用spring的AOP代理对象生成策略:

1.在spring中默认条件下如果目标对象有接口,则使用JDK的动态代理.
 如果目标对象没有接口则默认使用cgLib动态代理.

2.当从容器中获取对象时,如果获取的对象满足切入点表达式.那么就会为其创
建代理对象.代理对象指定方法就会执行与切入点绑定的通知方法.

原文地址:https://www.cnblogs.com/chenxiaoxian/p/10431170.html