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