代理模式是对象的结构模式,代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。


在代理模式中的介绍如下:

1)抽象对象角色:声明了目标对象和代理对象的共同接口,这样一来在任何可以使用目标对象的地方都可以使用代理对象。

2)目标对象角色:定义了代理对象所代表的目标对象。

3)代理对象角色:代理对象内部含有目标对象的引用,从而可以在任何时候操作目标对象;代理对象提供一个与目标对象相同的接口,以便可以在任何时候替代目标对象。代理对象通常在客户端调用传递给目标对象之前或之后,执行某个操作,而不是单纯地将调用传递给目标对象。


举例如逢年过节加班比较忙没有时间去买火车票,打电话给附近的票务中心叫他们帮忙代购;但是票务中心并非卖票的,只有火车站才是真正出售票的地点,票务中心其实是通过火车站实现的。


1. 静态代理

接口(或抽象类),具体代码如下:

package com.yoodb;

public interface Business {
	public void doAction();
}


此处是真正意义上实现业务逻辑的类,具体代码如下:

package com.yoodb;

public class BusinessImpl implements Business {

	@Override
	public void doAction() {
		// TODO Auto-generated method stub
		System.out.println("实现业务逻辑.");
	}

}


自己并未实现业务逻辑接口,而是调用实现,具体代码如下:

package com.yoodb;

public class BusinessImplProxy implements Business{
	
	private BusinessImpl impl;
	
	@Override
	public void doAction() {
		// TODO Auto-generated method stub
		if(impl == null){
			impl = new BusinessImpl();
		}
		doBefore();
		impl.doAction();
		doAfter();
	}
	private void doBefore(){  
        System.out.println("调用目标对象前做相关操作");  
    }  
	
    private void doAfter(){  
        System.out.println("调用目标对象后做相关操作");  
    } 
}


单元测试,具体代码如下:

package com.yoodb;

public class MainTest {
	public static void main(String[] args) {
		Business business = new BusinessImplProxy();
		business.doAction();
	}
}


运行之后结果如下:

调用目标对象前做相关操作
实现业务逻辑.
调用目标对象后做相关操作


2. 动态代理

Java动态代理类位于Java.lang.reflect包下,一般主要涉及到以下两个类:

1) Interface InvocationHandler:该接口中仅定义了一个方法Object:invoke(Object obj,Method method, Object[] args)。在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,args为该方法的参数数组;这个抽象方法在代理类中动态实现。


2) Proxy:该类即为动态代理类,作用类似于上例中的ProxySubject,其中主要包含以下内容:

Protected Proxy(InvocationHandler h):构造函数,估计用于给内部的h赋值。

Static Class getProxyClass (ClassLoader loader, Class[] interfaces):获得一个代理类,其中loader是类装载器,interfaces是真实类所拥有的全部接口的数组。

Static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h):返回代理类的一个实例,返回后的代理类可以当作被代理类使用(可使用被代理类的在Subject接口中声明过的方法)。


接口(或抽象类),具体代码如下:

package com.yoodb;

public interface Business {
	public void doAction();
}

此处是真正意义上实现业务逻辑的类,具体代码如下:
package com.yoodb;

public class BusinessImpl implements Business {

	@Override
	public void doAction() {
		// TODO Auto-generated method stub
		System.out.println("实现业务逻辑.");
	}

}


动态代理方式,具体代码如下:

package com.yoodb;

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

public class DynamicBusinessProxy implements InvocationHandler{
	
	private Object obj;
	
	public DynamicBusinessProxy() {}
	
	public DynamicBusinessProxy(Object obj) {
		this.obj = obj;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		// TODO Auto-generated method stub
		Object result = null;
		doBefore();
		result = method.invoke(obj, args);
		doAfter();		
		return result;
	}

	private void doBefore(){  
        System.out.println("调用目标对象前做相关操作");  
    }  
	
    private void doAfter(){  
        System.out.println("调用目标对象后做相关操作");  
    }
    
    public static Object factory(Object obj)  
    {  
        Class<? extends Object> cls = obj.getClass();
        return Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),new DynamicBusinessProxy(obj));  
    } 
}


单元测试,具体代码如下:

package com.yoodb;

public class MainTest {
	public static void main(String[] args) {
		Business business = (Business) DynamicBusinessProxy.factory(new BusinessImpl());
		business.doAction();
	}
}


运行之后结果如下:

调用目标对象前做相关操作
实现业务逻辑.
调用目标对象后做相关操作

评论

分享:

支付宝

微信