Spring之动态代理两种实现

Posted in-the-game-of-thrones

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring之动态代理两种实现相关的知识,希望对你有一定的参考价值。

基于jdk实现的动态代理

技术图片
 1 package com.proxy.daili;
 2 
 3 import com.proxy.daili.service.IModelMath;
 4 
 5 import java.lang.reflect.InvocationHandler;
 6 import java.lang.reflect.Method;
 7 import java.lang.reflect.Proxy;
 8 import java.util.Arrays;
 9 
10 /**
11  * 动态代理模式类
12  * 第一种代理模式:Jdk动态代理
13  *      注意:实现InvocationHandler这个接口
14  *
15  *      基于接口的
16  */
17 public class JdkDynamicProxy implements InvocationHandler 
18 
19     //定义需要代理的接口
20     protected IModelMath iModelMath;
21 
22     //将需要代理的接口作为参数传入到动态代理设计模式类中
23     public JdkDynamicProxy(IModelMath iModelMath)
24         this.iModelMath = iModelMath;
25     
26 
27     /**
28      * 生成代理对象
29      * 使用java.lang.reflect.Proxy这个类调用newProxyInstance方法
30      * 返回 动态代理类对象
31      */
32     public IModelMath iModelMathmethod()
33         IModelMath iModelMathProxy = (IModelMath) Proxy.newProxyInstance(iModelMath.getClass().getClassLoader(),
34                 iModelMath.getClass().getInterfaces(),
35                 this);
36         return iModelMathProxy;
37     
38 
39     /**
40      * 开始做代理的操作
41      * Object proxy 代理对象的引用
42      * Method method 当前执行的方法
43      * Object[] args  当前执行方法的参数
44      * 返回  与被代理对象返回的值相同
45      */
46     @Override
47     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable 
48         System.out.println("你调用的方法为:"+method.getName());
49         System.out.println("你调用的方法参数有:"+ Arrays.toString(args));
50         Object invoke = method.invoke(iModelMath, args);
51         System.out.println("方法的返回数据:"+invoke);
52         return invoke;
53     
54 
55 
View Code
技术图片
 1 package com.proxy.test;
 2 
 3 import com.proxy.daili.service.IModelMath;
 4 import com.proxy.daili.JdkDynamicProxy;
 5 import com.proxy.daili.service.ModelMath;
 6 import org.junit.Test;
 7 
 8 public class TestJDKDynamicProxy 
 9 
10     /**
11      * 使用jdk方式的动态代理
12      * 测试
13      */
14     @Test
15     public void testJdkDynamicProxy()
16         //需要被代理的动态对象
17         IModelMath imm = new ModelMath();
18         //代理对象
19         IModelMath math = new JdkDynamicProxy(imm).iModelMathmethod();
20         //通过代理对象做操作
21         int addition = math.addition(10, 2);
22         int subtraction = math.subtraction(20, 19);
23         System.out.println("实际方法的数据为:"+addition);
24         System.out.println("实际方法的数据为:"+subtraction);
25     
26 
View Code

基于gcLib实现的动态代理

技术图片
 1 package com.proxy.daili;
 2 
 3 import com.proxy.daili.service.IModelMath;
 4 import com.proxy.daili.service.ModelMath;
 5 import net.sf.cglib.proxy.Enhancer;
 6 import net.sf.cglib.proxy.MethodInterceptor;
 7 import net.sf.cglib.proxy.MethodProxy;
 8 
 9 import java.lang.reflect.Method;
10 import java.util.Arrays;
11 
12 /**
13  * cglib动态代理设计类
14  *  前提必须要先导入 cglib  包
15  *  基于 实现类的
16  */
17 public class CglibDynamicProxy implements MethodInterceptor 
18 
19     //定义被代理的实现类(注意这   是实现类,不是接口)
20     private ModelMath modelMath;
21 
22     //将被代理的对象作为参数  传入到 cglib动态代理设计类中
23     public CglibDynamicProxy(ModelMath modelMath)
24         this.modelMath = modelMath;
25     
26 
27     //生成代理对象
28     public ModelMath getProxyModelMath()
29         //new 一个Enhancer对象
30         Enhancer enhancer = new Enhancer();
31         //指定他的父类(注意这   是实现类,不是接口)
32         enhancer.setSuperclass(ModelMath.class);
33         //指定真正做事情的回调方法
34         enhancer.setCallback(this);
35         //生成代理类对象
36         ModelMath o = (ModelMath) enhancer.create();
37         //返回
38         return o;
39     
40 
41     /**
42      * 执行被代理的任何方法,都会经过这个方法
43      * @param o
44      * @param method
45      * @param objects
46      * @param methodProxy
47      * @return
48      * @throws Throwable
49      */
50     @Override
51     public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable 
52         System.out.println("通过gclib 动态代理调用的方法名为:"+method.getName());
53         System.out.println("通过gclib 动态代理调用的方法的参数包含:"+ Arrays.toString(objects));
54         Object invoke = method.invoke(modelMath, objects);
55         System.out.println("通过gclib 动态代理调用的方法返回的数据:"+ invoke);
56         return invoke;
57     
58 
View Code
技术图片
 1 package com.proxy.test;
 2 
 3 import com.proxy.daili.CglibDynamicProxy;
 4 import com.proxy.daili.service.ModelMath;
 5 import org.junit.Test;
 6 
 7 public class TestCgLibDynamicProxy 
 8     /**
 9      * 使用gclib方式的动态代理
10      * 测试
11      */
12     @Test
13     public void testCglibDynamicProxy()
14         ModelMath modelMath = new ModelMath();
15         ModelMath proxyModelMath = new CglibDynamicProxy(modelMath).getProxyModelMath();
16         int subtraction = proxyModelMath.subtraction(1, 44);
17         int addition = proxyModelMath.addition(10, -1);
18         System.out.println("执行减法得到的正式数据为:"+subtraction);
19         System.out.println("执行加法得到的正式数据为:"+addition);
20     
21 
View Code

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

SpringCloud系列之Feign-4.Feign的动态代理

学习笔记Spring中的动态代理

学习笔记Spring中的动态代理

Spring的两种动态代理:Jdk和Cglib 的区别和实现

Spring的两种动态代理:Jdk和Cglib 的区别和实现

Spring之AOP理解及使用