spring源码学习之【准备】jdk动态代理例子
一:被代理的对象所要实现的接口
1 package com.yeepay.testpoxy; 2 3 import java.util.Map; 4 5 /** 6 * 被动态代理的接口 7 * @author shangxiaofei 8 * 9 */ 10 public interface MyCheckPay { 11 /** 12 * 付钱的接口 13 * @param name 14 * @param money 15 * @return 16 */ 17 public Map<String, String> payMoney(String name,Integer money); 18 }
二:被动态代理的实现类
1 package com.yeepay.testpoxy; 2 3 import java.util.HashMap; 4 import java.util.Map; 5 6 /** 7 * 被动态代理的实现类 8 * @author shangxiaofei 9 * 10 */ 11 public class ShangxiaofeiMyCheckPay implements MyCheckPay{ 12 13 @Override 14 public Map<String, String> payMoney(String name, Integer money) { 15 System.out.println("ShangxiaofeiMyCheckPay.payMoney()========>name=["+name+"],payMoney=["+money+"]"); 16 Map<String, String> map=new HashMap<String, String>(); 17 map.put("result",name+"付钱"+money+"元,已经结束"); 18 return map; 19 } 20 21 22 23 }
三:动态代理的增强类(代理类)
1 package com.yeepay.testpoxy; 2 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Method; 5 6 /** 7 * 增加功能的类 8 * @author shangxiaofei 9 * 10 */ 11 public class HandlerForMyCheckPay implements InvocationHandler{ 12 /** 13 * 被委托的类的引用 14 */ 15 private Object object; 16 17 18 19 /** 20 * 空构造 21 */ 22 public HandlerForMyCheckPay() { 23 24 } 25 26 27 28 /** 29 * 有参构造 30 * @param object 31 */ 32 public HandlerForMyCheckPay(Object object) { 33 this.object = object; 34 } 35 36 37 38 39 /** 40 * Object proxy:指代我们所代理的那个真实对象,这个对象不能使用,否则会引起栈溢出 41 * Method method: 指代的是我们所要调用真实对象的某个方法的Method对象 42 * Object[] args: 指代的是调用真实对象某个方法时接受的参数 43 */ 44 @Override 45 public Object invoke(Object proxy, Method method, Object[] args)throws Throwable { 46 47 /** 48 * 被代理对象调用方法之前调用(aop的前置增强) 49 */ 50 System.out.println("HandlerForMyCheckPay.invoke()=======>【付钱前】向统计系统发送付钱消息"); 51 if(args!=null&&args.length>0){ 52 for(int i=0;i<args.length;i++){ 53 System.out.println("HandlerForMyCheckPay.invoke()发送消息为===>"+args[i]); 54 } 55 } 56 57 58 /** 59 * 调用被代理对象的实际的方法 60 */ 61 Object d=method.invoke(this.object, args); 62 63 64 /** 65 * 调用被代理对象的实际的方法之后执行:后置增强 66 */ 67 System.out.println("HandlerForMyCheckPay.invoke()=======>【付钱后】进行计算执行时长"); 68 69 return d; 70 } 71 72 73 74 }
四:代理类的生产工厂
1 package com.yeepay.testpoxy; 2 3 import java.lang.reflect.Proxy; 4 5 /** 6 * 生产代理者的工厂类 7 * @author shangxiaofei 8 * 9 */ 10 public class ProxyFactory { 11 12 public static MyCheckPay getMyCheckPay(){ 13 14 /** 15 * ClassLoader loader:一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载 16 * Class<?>[] interfaces: 一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了 17 * InvocationHandler h:一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上 18 */ 19 Object object=Proxy.newProxyInstance(ProxyFactory.class.getClassLoader(), new Class[]{MyCheckPay.class},new HandlerForMyCheckPay(new ShangxiaofeiMyCheckPay())); 20 return (MyCheckPay) object; 21 } 22 23 24 public static MyCheckPay getMyCheckPay2(){ 25 26 /** 27 * ClassLoader loader:一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载 28 * Class<?>[] interfaces: 一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了 29 * InvocationHandler h:一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上 30 */ 31 Object object=Proxy.newProxyInstance(ProxyFactory.class.getClassLoader(),MyCheckPay.class.getInterfaces(),new HandlerForMyCheckPay(new ShangxiaofeiMyCheckPay())); 32 return (MyCheckPay) object; 33 } 34 }
五:测试类
1 package com.yeepay.testpoxy; 2 3 import java.util.Map; 4 5 /** 6 * 测试动态代理 7 * @author shangxiaofei 8 * 9 */ 10 public class TestController { 11 12 private MyCheckPay myCheckPay=ProxyFactory.getMyCheckPay(); 13 14 public void payMoney(String name,Integer money){ 15 System.out.println("TestController.payMoney(开始)"); 16 Map<String, String> map=myCheckPay.payMoney(name, money); 17 System.out.println("TestController.payMoney(结束)"+map.get("result")); 18 } 19 20 /** 21 * TestController.payMoney(开始) 22 *HandlerForMyCheckPay.invoke()=======>【付钱前】向统计系统发送付钱消息 23 *HandlerForMyCheckPay.invoke()发送消息为===>怪物雷克 24 *HandlerForMyCheckPay.invoke()发送消息为===>100 25 *ShangxiaofeiMyCheckPay.payMoney()========>name=[怪物雷克],payMoney=[100] 26 *HandlerForMyCheckPay.invoke()=======>【付钱后】进行计算执行时长 27 *TestController.payMoney(结束)怪物雷克付钱100元,已经结束 28 * @param args 29 */ 30 public static void main(String[] args) { 31 TestController testController=new TestController(); 32 testController.payMoney("怪物雷克", 100); 33 } 34 35 }