代理模式的概念
代理模式就是屏蔽用戶對真實對象的訪問,而是使用代理對象完成用戶的請求。代理對象可以完成真實對象的所有功能,也可以添加特有的和真實對象無關的新功能。
生活中也常常見到代理模式的應用,例如我們可以到火車票代理點去購買火車票,代理點就是代理對象,替代火車站售票處來做發售車票的工作。著名的spring框架核心功能AOP也是應用了代理模式,將業務代碼和系統代碼解耦分離。
代理模式也能用來實現延遲加載功能,很多組件例如建立數據庫的連接需要消耗大量的系統資源,軟件啓動時如果默認加載會造成資源浪費,因此我們初始化代理類,當用戶執行數據庫操作時,再進行數據庫連接,加快了初始化的速度。
靜態代理
下面用一個例子說明最普通代理模式:
public class Proxy {
public static void main(String[] args) {
//實例化代理類
ProxyHello ph = new ProxyHello();
ph.sayHello("李藝彤");
}
}
interface IHello {
//定義接口
public void sayHello(String name);
}
class Hello implements IHello{
public void sayHello(String name){
System.out.println("你好," + name);
}
}
class ProxyHello implements IHello{
private Hello hello;
private String name;
public void proxyHello(String name){
this.name = name;
}
public void sayHello(String name) {
hello = new Hello();
hello.sayHello(name);
}
}
動態代理
動態代理更加的靈活,根據調用的代理類方法動態生成代理類,避免了大量書寫代理類接口的麻煩,而且也更易維護。
動態代理類必須實現InvocationHandler接口,通過調用這個接口的invoke方法來實現代理.
public class DynamicProxy {
public static void main(String[] args) {
//真實對象
IGoodbye goodbye = new Goodbye();
//傳入代理對象調用的真實對象
InvocationHandler handler = new ProxyGoodbye(goodbye);
//通過Proxy的newProxyInstance方法來創建我們的代理對象
//handler.getClass().getClassLoader()是代理對象
//goodbye.getClass().getInterfaces()是給代理對象提供的接口
IGoodbye object = (IGoodbye)Proxy.newProxyInstance(handler.getClass().getClassLoader(), goodbye
.getClass().getInterfaces(), handler);
object.sayGoodbye("李藝彤");
}
}
interface IGoodbye {
//定義接口
public void sayGoodbye(String name);
}
//真實對象
class Goodbye implements IGoodbye{
public void sayGoodbye(String name) {
System.out.println("再見," + name);
}
}
//代理對象
class ProxyGoodbye implements InvocationHandler{
private Object object1;
public ProxyGoodbye(Object object){
this.object1 = object;
}
/**
* @param object 代理的真實對象
* @param method 代理的方法
* @param args 傳入的參數
*/
public Object invoke(Object object2, Method method, Object[] args)
throws Throwable {
method.invoke(object1, args);
return null;
}
}