java代理模式(Proxy Pattern)
阿新 • • 發佈:2019-02-13
一、代理模式的概念
代理模式的定義:為其他物件提供一種代理以控制對這個物件的訪問。在某些情況下,一個物件不適合或者不能直接引用另一個物件,而代理物件可以在客戶端和目標物件之間起到中介的作用。
二、代理分類
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. 封裝真實的主題類,將真實的業務邏輯隱藏,只暴露給呼叫者公共的主題介面。