SSM(六)JDK动态代理和Cglib动态代理
1.Cglib动态代理
目标类:
1 package cn.happy.proxy.cglib; 2 3 public class Service { 4 public Service() { 5 System.out.println("创建Service对象"); 6 } 7 8 public void doWordk(){ 9 System.out.println("do something"); 10 } 11 }
测试:
1 package cn.happy.proxy.cglib; 2 3 import net.sf.cglib.proxy.Enhancer; 4 import net.sf.cglib.proxy.MethodInterceptor; 5 import net.sf.cglib.proxy.MethodProxy; 6 7 import java.lang.reflect.Method; 8 9 public class CglibTest { 10 public static void main(String[] args) { 11 //对方法增强。开闭原则-对修改关闭,对添加放开 12 //1.创建一个目标对象 13 Service service=new Service(); 14 //2.Enhancer对象 15 Enhancer enhancer=new Enhancer(); 16 enhancer.setSuperclass(service.getClass()); 17 //3.调度setCallBack() 18 enhancer.setCallback(new MethodInterceptor() { 19 @Override 20 public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { 21 System.out.println("write log"); 22 methodProxy.invoke(service,objects); 23 return null; 24 } 25 }); 26 //4.Enhancer对象的Create()方法创建代理 27 Service proxy =(Service) enhancer.create(); 28 //5.执行代理方法 29 proxy.doWordk(); 30 } 31 }
测试结果:
测试第27行enhancer.create()方法调用了Service的构造器。
create()方法是生成代理对象,其本质是目标类的子类实例,所以会调用父类构造。
2.JDK动态代理
jdk动态代理原理是动态生成目标对象实现接口的实现类。
接口:
1 package cn.happy.proxy.jdk; 2 3 public interface IService { 4 public void doWordk(); 5 }
目标类:
1 package cn.happy.proxy.jdk; 2 3 public class ServiceImpl implements IService{ 4 public ServiceImpl() { 5 System.out.println("创建Service对象"); 6 } 7 @Override 8 public void doWordk(){ 9 System.out.println("do something"); 10 } 11 }
测试:
1 package cn.happy.proxy.jdk; 2 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Method; 5 import java.lang.reflect.Proxy; 6 7 public class JdkTest { 8 public static void main(String[] args) { 9 ServiceImpl service = new ServiceImpl(); 10 IService proxy = (IService)Proxy.newProxyInstance(service.getClass().getClassLoader(), service.getClass().getInterfaces(), new InvocationHandler() { 11 @Override 12 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 13 System.out.println("write log"); 14 method.invoke(service, args); 15 return null; 16 } 17 }); 18 proxy.doWordk(); 19 } 20 }
测试结果:
3.比较
这里从网上摘了点儿东西
JDK动态代理:代理类和目标类必须实现相同的接口,客户端通过代理类来调用目标方法,代理类会将所有的方法调用分派到目标对象上反射执行,还可以在分派过程中添加"前置通知"和后置处理。
CGLIB动态代理:动态生成一个要代理类的子类,子类重写要代理的类的所有不是final的方法。在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。它比使用java反射的JDK动态代理要快。