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

  • 相关阅读:
    各种颜色对应的16进制
    django之旅 1.hello world
    FlexPaper文档在线浏览
    windwos下django 安装配置
    Josn 序列化
    WCF服务
    easy_install遇上Unable to find vcvarsall.bat
    Android开发环境搭建(jdk+eclip+android sdk)
    安卓系统架构图(转)
    windows8和windows server2012不联网安装.net 3.5(包括2.0和3.0)
  • 原文地址:https://www.cnblogs.com/tomasman/p/7669109.html
Copyright © 2020-2023  润新知