好久不碰java了,无聊突然想到咋动态代理,具体细节已经模糊了,再复习复习:
1 假设有一个类A实现了接口IMove,里面有move方法,现在要在move上面加一层(时间啊,日志之类的)
public class A implement s IMove{
public void move(){
System.out.println("move");
}
}
最常见的做法就是写个AProxy类实现IMove
public class AProxy implements IMove{
public AProxy(IMove m ){
this.m = m;
}
private IMove m;
public void move(){
System.out.println("move前");
this.m.move();
System.out.println("move后");
}
}
public class test{
public static void main(String[]args){
IMove a = new A();
IMove proxy = new AProxy(a);
proxy.move
}
}
2 动态代理
假设有一个Proxy能够生成所有的代理类,里面已经包含了代理的东西,那么就不用针对某个类写Proxy了
public class Proxy{
public static Object newProxyInstance(){
//假数据
return new Object();
}
}
public class test{
public static void main(String[]args){
//a这个对象应该在Proxy里面被创建
//IMove a = new A();
IMove proxy = (IMove)Proxy.newProxyInstance();
proxy.move();
}
现在重点就在如何写Proxy中的newProxyInstance方法了
3 newProxyInstance方法
将AProxy类中的代码先编译,编译后load到内存中
Class c = load到内存中的类
Constructor ctr = c.getConstructor(IMove.class);
//由于构造方法里面是要一个参数的,所以讲原来test里面的new A()也放到Proxy的newProxyInstance()里面
IMove m = (IMove)ctr.newInstance(new A());
return m;
这样IMove接口的代理就搞定了
4 实现所有接口的代理类(将接口传入代理类中)
1)public static Object newProxyInstance(Class inf){
/* 假数据
public class AProxy implements inf{
public AProxy(IMove m ){
this.m = m;
}
private IMove m;
public void move(){
System.out.println("move前");
this.m.move();
System.out.println("move后");
}
}
Class c = load到内存中的类
Constructor ctr = c.getConstructor(IMove.class);
Object m = (IMove)ctr.newInstance(new A()); return m;
}
2) 找到inf中的所有方法
public static Object newProxyInstance(Class inf){
/* 假数据
public class AProxy implements inf{
Method methods = inf.getMethods();
for(Method method : methods){
//把原来的move方法换成了传入参数的方法
public void method.getName(){
System.out.println("move前");
this.m.method();
System.out.println("move后"); }
public AProxy(IMove m ){
this.m = m;
}
private IMove m;
}
}
这样就看不到代理类了,而且可以产生所有的代理类,但现在的Proxy中的代理的内容是写死的,比如只能写move前,move后,而且里面的参数还是private Moveable m
3)建立可以由别人指定的方法处理
public interface InvocationHandler{
public void invoke(Object obj,Method m);
}
//实现类里将被代理的对象设置为属性
public class TimeHandler implements InvocationHandler{
private A a;
public TimeHandler(A a){
this.a = a
}
//注意obj中调用this的,在这里其实是没用的,但也可能会有用的,在invoke里面可能会有用,obj是内存生成的代理对象(jdk中应该用到了)
public void invoke(Object o,Method method){
System.out.println("move前");
method.invoke(a,new Obejct[]{});
System.out.println("move后"); }
}
这时Proxy中的方法就变成了这样
public static Object newProxyInstance(Class inf,InvocationHandler handler){
/* 假数据
public class AProxy implements inf{
Method methods = inf.getMethods();
for(Method method : methods){
//把原来的move方法换成了传入参数的方法
public void method.getName(){
Method md = inf.getName.class.getMethod(method.getName())
handler.invoke(this,md);
}
public AProxy(InvocationHandler handler ){
this.h= h;
}
//private IMove m; 原始的对象没了
private Invocation Handler h;
}
}
这时候能实现方式由他人指定了,但被代理的对象没了,就是原始的对象没了,
这样test就变为了
public class test{
public static void main(String[]args){
A a = new A();
InvocationHandler handler = new TimeHandler(a);
//这里要求 A实现了IMove接口
IMove proxy = (IMove)Proxy.newProxyInstance(IMove.class,handler);
proxy.move()
}
JDK中的动态代理
Proxy类
newProxyIntance(ClassLoader loader,Class<?>..,InvocationHandler h)
具体的JDK动态代理源码分析转载下http://rejoy.iteye.com/blog/1627405
自己写的自己忘了的时候再看看