代理模式——proxy pattern
阿新 • • 發佈:2019-02-05
代理模式的核心作用是,控制對物件的訪問,可以詳細控制訪問某個物件的方法,在呼叫這個方法前做前置處理,呼叫這個方法後做後置處理。這也是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();
}
}
這樣就是實現了動態代理,具體動態代理的原理是怎樣的呢??博主在下一篇進行簡單的分析。