1. 程式人生 > >java代理模式(Proxy Pattern)

java代理模式(Proxy Pattern)

一、代理模式的概念

代理模式的定義:為其他物件提供一種代理以控制對這個物件的訪問。在某些情況下,一個物件不適合或者不能直接引用另一個物件,而代理物件可以在客戶端和目標物件之間起到中介的作用。

二、代理分類

1、靜態代理

    代理類由程式設計師建立,程式執行前已經確定了代理類和被代理類的對應關係。

2、動態代理

    代理類不由程式設計師建立,程式執行期間建立代理類物件。

3、cglib代理(暫時不寫)

三、程式碼實現

1、靜態代理

1>建立介面

package com.test.proxy;
public interface Subject {
	void request();
}

2>建立真實物件實現介面

package com.test.proxy;
public class RealSubject implements Subject{
	@Override
	public void request() {		
		System.out.println("真實物件-----------");
	}
}

3>建立代理物件實現介面

package com.test.proxy;
public class ProxySubject implements Subject{	
	private Subject subject;	
	public ProxySubject(Subject subject) {
		this.subject = subject;
	}
	@Override
	public void request() {		
		System.out.println("begin");
		subject.request();
		System.out.println("end");		
	}
}

4>測試類

package com.test.proxy;

public class ProxyTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		RealSubject realSubject = new RealSubject();
		ProxySubject pSubject = new ProxySubject(realSubject);
		pSubject.request();
		
//		ProxyFactory.getIntance().request();
	}

}
------------測試結果-----------
begin
真實物件-----------
end

5>建立代理類工廠(使用代理時不用每次都建立代理類物件和真實類物件)

package com.test.proxy;

public class ProxyFactory {
	
	public static Subject getIntance(){
		
		return new ProxySubject(new RealSubject());
	}
}

2、動態代理

1>建立介面

package com.test.dynamicproxy;

public interface DynamicProxy {
	
	void request(String str);
}

2>建立真實物件實現介面

package com.test.dynamicproxy;

public class RealObj implements DynamicProxy{

	@Override
	public void request(String str) {
		
		System.out.println("動態代理真實物件=======" + str);
	}
	
}

3>建立代理物件實現jdk中的InvacationHandler介面

package com.test.dynamicproxy;

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

public class ProxyObj implements InvocationHandler{
	
	private Object target;
	
	public ProxyObj(Object target) {
		this.target = target;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		
		System.out.println("進入代理類---------");
		Object object = method.invoke(target, args);
		System.out.println("執行完真實類方法之後--------");
		return object;
	}
	
	/**
	 * 獲取代理物件
	 * @return
	 */
	public Object getProxy(){
		
		return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), 
				target.getClass().getInterfaces(), this);
	}

}

4>測試類

package com.test.dynamicproxy;

public class TestDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		DynamicProxy real = new RealObj();
		ProxyObj inHandler = new ProxyObj(real);
		DynamicProxy dyProxy = (DynamicProxy) inHandler.getProxy();
		dyProxy.request("1111");
	}

}
----------測試結果----------
進入代理類---------
動態代理真實物件=======1111
執行完真實類方法之後--------
四、應用場景

    1.在原方法執行之前和之後做一些操作,可以用代理來實現(比如記錄Log,做事務控制等)。 
    2.
封裝真實的主題類,將真實的業務邏輯隱藏,只暴露給呼叫者公共的主題介面。