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
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
基于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
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
以上是关于Spring之动态代理两种实现的主要内容,如果未能解决你的问题,请参考以下文章
SpringCloud系列之Feign-4.Feign的动态代理
Spring的两种动态代理:Jdk和Cglib 的区别和实现