`

java动态代理模式

阅读更多
代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。
在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

代理模式一般涉及到的角色有:
   1.抽象角色:声明真实对象和代理对象的共同接口; <接口 Material>
   2.代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装; <包含真是对象 Object>
  3.真实角色:代理角色所代表的真实对象,是我们最终要引用的对象; <MaterialImpl>


在使用动态代理类时,我们必须实现InvocationHandler接口
   Interface InvocationHandler:
  •   该接口中仅定义了一个方法Object:invoke(Object obj,Method method, 在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,如上例中的request(),args为该方法的参数数组。这个抽象方法在代理类中动态实现。

(2).Proxy:该类即为动态代理类,其中主要包含以下内容:
 
  •  Protected Proxy(InvocationHandler h):构造函数,估计用于给内部的h赋值。   Static Class getProxyClass (ClassLoader loader, Class[] interfaces):获得一个代理类,其中loader是类装载器,interfaces是真实类所拥有的全部接口的数组。   
  • Static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h):返回代理类的一个实例,返回后的代理类可以当作被代理类使用(可使用被代理类的在Subject接口中声明过的方法)。

 所谓Dynamic Proxy是这样一种class:它是在运行时生成的class,在生成它时你必须提供一组interface给它,然后该class就宣称它实现了这些 interface。你当然可以把该class的实例当作这些interface中的任何一个来用。当然啦,这个Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作

public class Client
{
	static public void main(String[] args) throws Throwable
	{

	 Material rs = new MaterialImpl(); // 在这里指定被代理类
		InvocationHandler ds = new DynamicMaterial(rs);
		Class<?> cls = rs.getClass();

		// 以下是一次性生成代理

	Material subject = (Material)
 Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), ds);//为代理类提供class和 接口,以及交给那个 DynamicMaterial来处理



	/*分布生成*/
		/*Class c = Proxy.getProxyClass(cls.getClassLoader(),cls.getInterfaces()) ;
		 Constructor ct=c.getConstructor(new Class[]{InvocationHandler.class}); 
		 Material sbSubject =(Material) ct.newInstance(new Object[]{ds}); 		
		sbSubject.request();*/
		
		subject.request();
	}
}



public class DynamicMaterial implements InvocationHandler
{
    private Object sub;
  //就是你需要代理的类,运行的时候其实就是MaterialImpl

    public DynamicSubject()
    {
    }

    public DynamicSubject(Object obj)
    {
        sub = obj;
    }

    //也就是利用反射机制调用里面的方法而已
	
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
    {
        System.out.println("before calling " + method);  //你要做的事情

        method.invoke(sub, args);

        System.out.println("after calling " + method);  //你要做的事情

        return null;
	}

}
2
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics