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动态代理要快。

posted @ 2017-10-14 23:56  Tomas曼  Views(625)  Comments(0Edit  收藏  举报