`
冲杯茶喝
  • 浏览: 29473 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Java动态代理源码学习,YY

 
阅读更多

今天看了下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()
	} 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics