【ThinkingInJava】43、与动态代理混合的装饰器模式
//: net/mindview/util/TwoTuple.java package net.mindview.util; public class TwoTuple<A,B> { public final A first; public final B second; public TwoTuple(A a, B b) { first = a; second = b; } public String toString() { return "(" + first + ", " + second + ")"; } } ///:~
package Lesson15_generices; //: generics/Mixins.java import java.util.*; interface TimeStamped { long getStamp(); } class TimeStampedImp implements TimeStamped { private final long timeStamp; public TimeStampedImp() { timeStamp = new Date().getTime(); } public long getStamp() { return timeStamp; } } interface SerialNumbered { long getSerialNumber(); } class SerialNumberedImp implements SerialNumbered { private static long counter = 1; private final long serialNumber = counter++; public long getSerialNumber() { return serialNumber; } } interface Basic { public void set(String val); public String get(); } class BasicImp implements Basic { private String value; public void set(String val) { value = val; } public String get() { return value; } } class Mixin extends BasicImp implements TimeStamped, SerialNumbered { private TimeStamped timeStamp = new TimeStampedImp(); private SerialNumbered serialNumber = new SerialNumberedImp(); public long getStamp() { return timeStamp.getStamp(); } public long getSerialNumber() { return serialNumber.getSerialNumber(); } } public class Mixins { public static void main(String[] args) { Mixin mixin1 = new Mixin(), mixin2 = new Mixin(); mixin1.set("test string 1"); mixin2.set("test string 2"); System.out.println(mixin1.get() + " " + mixin1.getStamp() + " " + mixin1.getSerialNumber()); System.out.println(mixin2.get() + " " + mixin2.getStamp() + " " + mixin2.getSerialNumber()); } } /* Output: (Sample) test string 1 1132437151359 1 test string 2 1132437151359 2 *///:~
/** * 书本:《Thinking In Java》 * 功能:与动态代理混合 * 文件:DynamicProxyMixin.java * 时间:2015年4月21日10:38:44 * 作者:cutter_point */ package Lesson15_generices; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.HashMap; import java.util.Map; import net.mindview.util.TwoTuple; import static net.mindview.util.Tuple.*; class MixinProxy implements InvocationHandler { Map<String, Object> delegetesByMethod; public MixinProxy(TwoTuple<Object, Class<?>>... pairs)//这句表示,多个TwoTuple<Object, Class<?>>类型的参数 { delegetesByMethod = new HashMap<String, Object>(); for(TwoTuple<Object, Class<?>> pair : pairs) { for(Method method : pair.second.getMethods()) //取得这个类的所有方法,遍历 { String methodName = method.getName(); if(!delegetesByMethod.containsKey(methodName)) //如果这个map包含这个指定键就返回true delegetesByMethod.put(methodName, pair.first); //吧有这个方法的类放进去和这个方法形成映射 } } } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String methodName = method.getName(); //取得方法的名字 Object delegate = delegetesByMethod.get(methodName); //根据方法名取得对应的方法 System.out.println("动态代理里面的invoke方法"); return method.invoke(delegate, args); //回调 } public static Object newInstance(TwoTuple... pairs) { Class interfaces[] = new Class[pairs.length]; //创建长度为pairs.length的Class数组 for(int i = 0; i < pairs.length; ++i) { interfaces[i] = (Class)pairs[i].second; //取得所有的类的方法,初始化这个数组,里面存放的是第二个参数,这里应该是类型信息 } //取得c1的类加载器,让代理类实现的时候使用同一个类加载器 ClassLoader cl = pairs[0].first.getClass().getClassLoader(); //返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。 /** * c1是代理对象使用的加载类,interfaces是代理类要实现的接口列表,第三个参数new MixinProxy(pairs)是指派方法调用的调用处理程序 */ return Proxy.newProxyInstance(cl, interfaces, new MixinProxy(pairs)); } } public class DynamicProxyMixin { public static void main(String[] args) { Object mixin = MixinProxy.newInstance( tuple(new BasicImp(), Basic.class), tuple(new TimeStampedImp(), TimeStamped.class), tuple(new SerialNumberedImp(),SerialNumbered.class)); Basic b = (Basic)mixin; TimeStamped t = (TimeStamped)mixin; SerialNumbered s = (SerialNumbered)mixin; b.set("cutter_point"); //调用set方法的时候,代理拦截,在实现之前执行代理 System.out.println(b.get()); //调用get方法了,再次触发 System.out.println(t.getStamp()); //同上 System.out.println(s.getSerialNumber()); //同上 } }
输出:
动态代理里面的invoke方法
动态代理里面的invoke方法
cutter_point
动态代理里面的invoke方法
1431995142154
动态代理里面的invoke方法
1
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。