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 }

    达成效果:

  • 相关阅读:
    Vuejs的一些总结
    vue.js中$emit的理解
    Vue.js——60分钟快速入门
    [ARC096E] Everything on It
    [ARC093E] Bichrome Spanning Tree
    [ARC093F] Dark Horse
    [ARC100F] Colorful Sequences
    卡特兰数 学习笔记
    【原】图练习
    【原】图
  • 原文地址:https://www.cnblogs.com/linsky/p/10415757.html
Copyright © 2011-2022 走看看