• 用javassist和CGLIB 解决JDK动态代理的缺陷




     用 javassist 解决 JDK 动态代理的缺陷

    • JDK动态代理的缺陷

        要求目标类必须实现接口,否则产生不了代理。有些场景下,目标类也要产生代理类但是木有实现接口,这个时间 Java 中有两个常用类库:1)javassist http://www.javassist.org/
      2) cglib 帮我们对木有实现接口的目标类产生代理

    • 添加依赖
    <dependency>
      <groupId>org.javassist</groupId>
      <artifactId>javassist</artifactId>
      <version>3.25.0-GA</version>
    </dependency
    • 新建类
    public class BookDaoImpl3 {
      public void insert() {
        System.out.println("插入书籍");
      }
      public void update() {
        System.out.println("修改书籍");
      }
      public void del() {
        ////
        System.out.println("删除书籍");
      }
    }
    • 测试代码
    public class Test03 {
    public static void main(String[] args) throws
    InstantiationException, IllegalAccessException {
    //租房子的人
    BookDaoImpl3 target=new BookDaoImpl3();
    //中介:基于 javassist 的动态代理,不要求实现代理
    ProxyFactory factory=new ProxyFactory();
    factory.setSuperclass(BookDaoImpl3.class);
    factory.setHandler(new MethodHandler() {
    @Override
    public Object invoke(Object self, Method thisMethod, 
    Method proceed, Object[] args) throws Throwable {
    //这里放置重复代码
    Object ret=null;
    try {
    System.out.println("============================");
    System.out.println("开启会话");
    ////
    ret= thisMethod.invoke(target, args);//让不同代
    码执行,不同代码再方法中
    ///
    System.out.println("事务提交");
    } catch (Exception e) {
    System.out.println("事务回滚");
    e.printStackTrace();
    } finally {
    System.out.println("关闭会话");
    }
    return ret;
    }
    });
    Class clazz=factory.createClass();
     
    BookDaoImpl3 proxy=(BookDaoImpl3) clazz.newInstance();
    proxy.del();
    proxy.update();
    proxy.insert();
    }
    }
    • 不同点分析

          


    用 CGLIB 解决 JDK 动态代理的缺陷

    • 添加依赖
    <dependency>
      <groupId>cglib</groupId>
      <artifactId>cglib</artifactId>
      <version>3.3.0</version>
    </dependency>
    • 测试
    public class Test04 {
    public static void main(String[] args) throws InstantiationException, 
    IllegalAccessException {
    //租房子的人
    BookDaoImpl3 target=new BookDaoImpl3();
    //中介:基于 CGLIB 的动态代理,不要求实现代理
    Enhancer enhancer=new Enhancer();
    enhancer.setSuperclass(BookDaoImpl3.class);
    enhancer.setCallback(new MethodInterceptor() {
    @Override
    public Object intercept(Object obj, Method method, Object[] args, 
    MethodProxy proxy) throws Throwable {
    //这里放置重复代码
    Object ret=null;
    try {
    System.out.println("============================");
    System.out.println("开启会话");
    ////
    ret= method.invoke(target, args);//让不同代码执行,不同代码再方法
    ///
    System.out.println("事务提交");
    } catch (Exception e) {
    System.out.println("事务回滚");
    e.printStackTrace();
    } finally {
    System.out.println("关闭会话");
    }
    return ret;
    }
    });
     
    BookDaoImpl3 proxy=(BookDaoImpl3) enhancer.create();
    proxy.del();
    proxy.update();
    proxy.insert();
    }
    }
    • 不同点分析



  • 相关阅读:
    WPF
    WPF RadioButton 转换
    JS框架之收集专帖
    WPF用ShowDialog()弹出窗体时控制该窗体的显示位置,并传值回父窗体
    WPF学习笔记:MVVM模式下,ViewModel如何关闭View?
    Microsoft Visual Studio 下载转帖
    RelayCommand命令
    动态调用webservice,不需要添加Web References
    你会在C#的类库中添加web service引用吗?
    Quartz Cron 触发器 Cron Expression 的格式
  • 原文地址:https://www.cnblogs.com/yuanshuai1026/p/11580713.html
Copyright © 2020-2023  润新知