zoukankan      html  css  js  c++  java
  • Cglib的动态代理

    Cglib是基于类的代理,不需要基于接口,会生成目标对象类型的子对象,所以当需要被代理的类没有继承接口时,就可以使用Cglib代理。

    过程如图所示:

    Cglib有三种类似的方式,下面一一举例,可能比较肤浅:

    目标类:

     1 /**
     2  * @author o_0sky
     3  * @date 2019/2/20 21:51
     4  */
     5 public class ProductService {
     6     public void save() {
     7         System.out.println("存钱");
     8     }
     9 
    10     public int find() {
    11         System.out.println("查询剩余");
    12         return 100;
    13     }
    14 }

    方式一(工厂直接实现MethodInterptor接口):

     1 import org.springframework.cglib.proxy.Enhancer;
     2 import org.springframework.cglib.proxy.MethodInterceptor;
     3 import org.springframework.cglib.proxy.MethodProxy;
     4 
     5 import java.lang.reflect.Method;
     6 
     7 /**
     8  * @author o_0sky
     9  * @date 2019/2/21 22:02
    10  */
    11 public class CglibFactory implements MethodInterceptor {
    12     //声明一个对象引用
    13     private Object target;
    14 
    15     //注入代理对象
    16     public CglibFactory(Object target) {
    17         this.target = target;
    18     }
    19 
    20     //获取代理对象
    21     public Object getProxyObject() {
    22         //代理对象生成器
    23         Enhancer enhancer = new Enhancer();
    24         //获取目标对象.class
    25         enhancer.setSuperclass(target.getClass());
    26         //获取目标对象类型的子类型
    27         enhancer.setCallback(this);
    28         //生成代理对象并返回
    29         Object proxy = enhancer.create();
    30         return proxy;
    31     }
    32 
    33     /**
    34      * @param o                  (代理对象)
    35      * @param method             (目标对象的方法对象)
    36      * @param args(目标对象的方法的参数的值)
    37      * @param methodProxy        (代理对象的方法对象)
    38      * @return
    39      * @throws Throwable
    40      */
    41     @Override
    42     public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
    43         //给目标对象的目标方法增强功能
    44         if ("sava".equals(method.getName())) {
    45             date();
    46         }
    47         //其他方法不作更改,照常执行,有返回值的返回
    48         Object invoke = method.invoke(target, args);
    49         return invoke;
    50     }
    51 
    52     //增强的保存日志方法
    53     private static void date() {
    54         System.out.println("操作日志保存了!");
    55     }
    56 }

    方式二(内部类实现MethodInterptor):

     1 import org.springframework.cglib.proxy.Enhancer;
     2 import org.springframework.cglib.proxy.MethodInterceptor;
     3 import org.springframework.cglib.proxy.MethodProxy;
     4 
     5 import java.lang.reflect.Method;
     6 
     7 /**
     8  * @author o_0sky
     9  * @date 2019/2/21 22:14
    10  */
    11 public class CglibFactory1 {
    12     private Object target;
    13 
    14     private static void date() {
    15         System.out.println("操作日志保存了!");
    16     }
    17 
    18     public Object getProxyObject() {
    19         Enhancer enhancer = new Enhancer();
    20         enhancer.setSuperclass(target.getClass());
    21         enhancer.setCallback(new MyImp());
    22         Object o = enhancer.create();
    23         return o;
    24     }
    25 
    26     class MyImp implements MethodInterceptor {
    27 
    28         @Override
    29         public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
    30             if ("save".equals(method.getName())) {
    31                 date();
    32             }
    33             Object invoke = method.invoke(target, objects);
    34             return invoke;
    35         }
    36     }
    37 }

    方式三(匿名内部类):

    import org.springframework.cglib.proxy.Enhancer;
    import org.springframework.cglib.proxy.MethodInterceptor;
    import org.springframework.cglib.proxy.MethodProxy;
    
    import java.lang.reflect.Method;
    
    /**
     * @author o_0sky
     * @date 2019/2/21 22:20
     */
    public class CglibFactory3 {
        private Object target;
    
        private static void date() {
            System.out.println("操作日志保存了!");
        }
    
        public Object getProxyObject() {
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(target.getClass());
            enhancer.setCallback(new MethodInterceptor() {
                @Override
                public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                    if ("save".equals(method.getName())) {
                        date();
                    }
                    Object invoke = method.invoke(target, objects);
                    return invoke;
                }
            });
            return enhancer.create();
        }
    
    }

    实现类:

     1 /**
     2  * @author o_0sky
     3  * @date 2019/2/21 22:24
     4  */
     5 public class DTest {
     6     public static void main(String[] args) {
     7         ProductService productService =new ProductService();
     8         CglibFactory factory =new CglibFactory(productService);
     9         ProductService proxyObject = (ProductService) factory.getProxyObject();
    10         proxyObject.save();
    11         System.out.println("~~~~~~~~~~~~~~~~~~~~");
    12         productService.find();
    13     }
    14 }

    达成效果:

  • 相关阅读:
    安装lnmp 时如何修改数据库数据存储地址及默认访问地址
    ubuntu 设置root用户密码并实现root用户登录
    解决ubuntu 远程连接问题
    linux 搭建FTP服务器
    PHP 根据ip获取对应的实际地址
    如何发布自己的composer包
    使用composer安装composer包报Your requirements could not be resolved to an installable set of packages
    laravel 框架配置404等异常页面
    使用Xshell登录linux服务器报WARNING! The remote SSH server rejected X11 forwarding request
    IoTSharp 已支持国产松果时序数据库PinusDB
  • 原文地址:https://www.cnblogs.com/linsky/p/10415757.html
Copyright © 2011-2022 走看看