Cglib的动态代理

Posted linsky

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }

达成效果:

技术图片

 

以上是关于Cglib的动态代理的主要内容,如果未能解决你的问题,请参考以下文章

Spring中的cglib动态代理

动态代理之 CGLIB 动态代理

代理模式(静态代理jdk动态代理CGLib动态代理)

AOP动态代理之CGLIB代理

JDK动态代理CGLIB动态代理

JDK动态代理CGLIB动态代理