设计模式学习之动态代理模式

import java.lang.reflect.Method;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

class InvocationHandlerImpl implements InvocationHandler {

	public Object object;

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		// TODO Auto-generated method stub
		Object result = method.invoke(object, args);// 注意如果方法是void,返回的是null
		return result;
	}

}
interface Handler{
	void execute();
}
class HandlerImpl1 implements Handler{

	@Override
	public void execute() {
		// TODO Auto-generated method stub
		System.err.println("1执行");
		
	}
	
}
class HandlerImpl2 implements Handler{

	@Override
	public void execute() {
		// TODO Auto-generated method stub
		System.err.println("2执行");
	}
	
}


public class Test {
	public static void main(String[] args) {
		Handler h = new HandlerImpl1();
		InvocationHandlerImpl invocationHandlerImpl = new InvocationHandlerImpl();
		invocationHandlerImpl.object = h;
		Handler hh =  (Handler) Proxy.newProxyInstance(Test.class.getClassLoader(), h.getClass().getInterfaces(), invocationHandlerImpl);
		hh.execute();

	}
}

以下测试更为全面:

		Handler h = new HandlerImpl1();
		InvocationHandlerImpl invocationHandlerImpl = new InvocationHandlerImpl();
		invocationHandlerImpl.object = h;
		Class<?>[] cs= h.getClass().getInterfaces();//获取接口集合
		System.err.println(cs[0]);
		Handler hh =  (Handler) Proxy.newProxyInstance(Test.class.getClassLoader(),cs, invocationHandlerImpl);	//invocationHandlerImpl要代理的对象
		
		hh.execute();	
		
		InvocationHandler i = Proxy.getInvocationHandler(hh);//获取实际类型
		Class<?> c =Proxy.getProxyClass(Test.class.getClassLoader(), h.getClass().getInterfaces());//被代理的动态对象的class对象
		//以下代码分析这个动态代理class的信息
		Method[] ms = c.getMethods();
		for(Method m:ms){
			System.err.println(m.getName());
			Class<?>[] cms = m.getParameterTypes();
			System.err.print("参数为:");
			for(Class<?> cm : cms){
				System.err.print(cm.getSimpleName()+"--");
			}
			
			if(cms.length==0){
				System.err.print("无参函数");
			}
			System.err.println("");
		}
		boolean b1 = Proxy.isProxyClass(h.getClass());
		boolean b2 = Proxy.isProxyClass(c);
		System.err.println(i.toString());
		System.err.println(c.toString());
		System.err.println(b1);
		System.err.println(b2);
		

	}
}

打印信息为:

interface wwx.test.Handler
前置处理
1执行
equals
参数为:Object--
toString
参数为:无参函数
hashCode
参数为:无参函数
execute
参数为:无参函数
isProxyClass
参数为:Class--
newProxyInstance
参数为:ClassLoader--Class[]--InvocationHandler--
getInvocationHandler
参数为:Object--
getProxyClass
参数为:ClassLoader--Class[]--
wait
参数为:无参函数
wait
参数为:long--int--
wait
参数为:long--
getClass
参数为:无参函数
notify
参数为:无参函数
notifyAll
参数为:无参函数
wwx.test.InvocationHandlerImpl@4aa298b7
class wwx.test.$Proxy0
false

true


解释:

以下都是动态代理类的,代理方法

equals
参数为:Object--
toString
参数为:无参函数
hashCode
参数为:无参函数
execute
参数为:无参函数
isProxyClass
参数为:Class--
newProxyInstance
参数为:ClassLoader--Class[]--InvocationHandler--
getInvocationHandler
参数为:Object--
getProxyClass
参数为:ClassLoader--Class[]--
wait
参数为:无参函数
wait
参数为:long--int--
wait
参数为:long--
getClass
参数为:无参函数
notify
参数为:无参函数
notifyAll

参数为:无参函数

和ide给出一样:



总结:

java的动态代理仅仅支持interface的代理,这里必须注意,不能对class进行动态代理,根本原因就是Java在

本质上多继承就是行不通的。javaScript可以动态代理,而且很容易实现,因为它是脚本语言,脚本语言可以

在代码中执行代码,那就很easy了啊。

猜你喜欢

转载自blog.csdn.net/qq_32771571/article/details/79706708
今日推荐