1. 程式人生 > >代理模式——proxy pattern

代理模式——proxy pattern

代理模式的核心作用是,控制對物件的訪問,可以詳細控制訪問某個物件的方法,在呼叫這個方法前做前置處理,呼叫這個方法後做後置處理。這也是Spring中AOP(面向切面程式設計)的核心機制。

代理模式分為靜態代理以及動態代理:

靜態代理【static proxy】:

在靜態代理中,代理物件與被代理物件必須實現同一個介面,完整保留被代理物件的介面樣式,並且一直保持介面不變原則。程式碼實現:


實現的同一個介面【實際上就是被代理物件的所有操作】

package proxy.staticproxy;
/**
 * 一個明星的相關操作
 * @author acer
 */
public interface Star {
	//籤協議
	void confer();
	
	//籤合同
	void signContract();
	
	//訂票
	void bookTicket();
	
	//唱歌
	void sing();
	
	//收錢
	void collectMoney();
}

實際類:
package proxy.staticproxy;
/**
 * 真實的明星,實現了這個介面
 * @author acer
 */
public class RealStar implements Star{

	@Override
	public void confer() {
		System.out.println("RealStar.confer()");
	}

	@Override
	public void signContract() {
		System.out.println("RealStar.signContract()");
	}

	@Override
	public void bookTicket() {
		System.out.println("RealStar.bookTicket()");
	}

	@Override
	public void sing() {
		System.out.println("歌手唱歌");
	}

	@Override
	public void collectMoney() {
		System.out.println("RealStar.collectMoney()");
	}

}

代理類:
package proxy.staticproxy;
/**
 * 代理類,實現Star介面,代理類必須持有被代理類的物件
 * @author acer
 */
public class ProxyStar implements Star{

	private Star star;
	
	public ProxyStar(Star star) {
		super();
		this.star = star;
	}

	@Override
	public void confer() {
		System.out.println("RealStar.confer()");
		
	}

	@Override
	public void signContract() {
		// TODO Auto-generated method stub
		System.out.println("RealStar.signContract()");
	}

	@Override
	public void bookTicket() {
		// TODO Auto-generated method stub
		System.out.println("RealStar.bookTicket()");
	}

	/**
	 * 唱歌的方法必須由被代理類自己實現
	 */
	@Override
	public void sing() {
		star.sing();
	}

	@Override
	public void collectMoney() {
		// TODO Auto-generated method stub
		System.out.println("RealStar.collectMoney()");
	}
}

測試:
package proxy.staticproxy;

public class Client {

	public static void main(String[] args) {
		Star real = new RealStar();
		Star proxy = new ProxyStar(real);
		
		proxy.confer();
		proxy.collectMoney();
		proxy.bookTicket();
		proxy.signContract();
		proxy.sing();
	}
}

動態代理【dynamic proxy】:實際上就是動態生成代理類


相比於靜態代理的優點:

JDK自帶的動態代理:

——java.lang.reflect.Proxy :作用是動態生成代理類和物件

——java.lang.reflect.InvocationHandler(處理器介面)

       可以通過invoke方法實現對真實角色的代理訪問

       每次通過Proxy生成代理類物件時,都要指定對應的物件處理器。

下面通過程式碼來實現以下jdk自帶的動態代理:

首先介面以及被代理類是相同的

代理類:

package proxy.dynamicproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
 * 動態的代理類必須實現處理器介面
 * @author acer
 */
public class StarHandler implements InvocationHandler{

	private Star realStar;
	
	public StarHandler(Star realStar) {
		super();
		this.realStar = realStar;
	}

	/**
	 * 通過這個方法實現對真實角色的代理訪問
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		if(method.getName().equals("sing")){
			method.invoke(realStar,args);
		}
		return null;
	}

}

代理類必須實現InvocationHandler介面
測試以下:
package proxy.dynamicproxy;

import java.lang.reflect.Proxy;

public class Client {
	public static void main(String[] args) {
		Star realstar = new RealStar();
		StarHandler handler = new StarHandler(realstar);
		/**
		 * 通過Proxy類的newProxyInstance()方法動態的建立代理類
		 */
		Star proxy = (Star) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Star.class}, handler);
		
		proxy.bookTicket();
		proxy.sing();
	}
}

這樣就是實現了動態代理,具體動態代理的原理是怎樣的呢??博主在下一篇進行簡單的分析。