//: 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