今天看了下java动态代理的源码,YY下实现,有错请指出
Java动态代理需要实现接口。为什么,Java是这么做的:
Java会根据需要代理类所实现的所有接口,创造一个实现了同样接口的Class对象,并通过类加载器加载。
这个类的构造器需要传入我们实现了InvocationHandler代理类。
当代理类调用接口的方法时,其实是用InvocationHandler.invoke,来实现。
举例:
类A implements B
B有一个方法handleb(String string);
动态代理类C
当B b = C.bind(A)的时候,Proxy会生成一个实现了B的代理类P,并缓存起来。再用P实例化一个B的实例。
P的构造器需要一个C的实例。
P的handleb(String s)方法是这么实现的(YY的)
handleb(String s){
c.invike(c,method,s);
}
c.invike(c,method,s);
c就是P类实例构造时候传入的C实例,也就是我们bind得到的代理类。(验证过)
method是B的handleb方法对应的Method实例。
测试代码:
public interface Sad {
void sad();
}
public class SadImpl implements Sad, Inter1 {
@Override
public void sad() {
System.out.println("桑心");
}
}
public class DynamicProxy implements InvocationHandler {
private Object target;
public static Object p;
public static Method m;
/**
* 绑定委托对象并返回一个代理类
*
* @param target
* @return
*/
public Object bind(Object target) {
this.target = target;
// 取得代理对象
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), this); // 要绑定接口(这是一个缺陷,cglib弥补了这一缺陷)
}
@Override
/**
* 调用方法
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result = null;
System.out.println("动态代理前");
// 执行方法
p = proxy.getClass();
m = method;
result = method.invoke(target, args);
System.out.println("动态代理后");
return result;
}
}
测试类:
@Test
public void testDynamicProxy() throws SecurityException,
NoSuchMethodException {
DynamicProxy proxy = new DynamicProxy();
Sad sad = (Sad) proxy.bind(new SadImpl());
sad.sad();
System.out.println(sad.getClass() == DynamicProxy.p);//true
System.out.println(Sad.class.getMethods()[0].equals(DynamicProxy.m));//true
System.out.println(Sad.class.getMethods()[0]);//public abstract void cn.teaey.test.proxy.Sad.sad()
System.out.println(DynamicProxy.m);//public abstract void cn.teaey.test.proxy.Sad.sad()
}