java中代理模式
前言
代理(Proxy)模式是一種結構型設計模式,提供了對目標對象另外的訪問方式——即通過代理對象訪問目標對象。
這樣做的好處是:可以在目標對象實現的基礎上,擴展目標對象的功能。
代理模式主要涉及三個角色:
Real Subject:目標類,也就是被代理類、委托類。用來真正完成業務服務功能;
Proxy:代理類,將自身的請求用 Real Subject 對應的功能來實現,代理類對象並不真正的去實現其業務功能;
Subject:定義 RealSubject 和 Proxy 角色都應該實現的接口。
正文
靜態代理
靜態代理需要先定義接口,被代理對象與代理對象一起實現相同的接口,代理類持有目標類的引用,然后通過調用相同的方法來調用目標對象的方法
代碼實例:
接口類 CarInterfaces.class,定義一組接口
interface CarInterfaces {
void run();
}
目標類 Car.class
public class Car implements CarInterfaces {
@Override
public void run() {
System.out.println("Car run()");
}
}
代理類 CarSystemProxy.class
public class CarSystemProxy implements CarInterfaces {
Car car;
@Override
public void run() {
System.out.println("before car run");
if (car == null) {
car = new Car();
}
car.run();
System.out.println("after car run");
}
}
測試類 CarTest.class
public class CarTest {
public static void main(String[] args) {
CarSystemProxy carSystemProxy = new CarSystemProxy();
carSystemProxy.run();
}
}
問題:當目標類接口增多后,代理類要代理新增的接口,如果按照靜態代理的模式,代理類中要同步新增接口,這時候就顯得比較麻煩,怎么才能優化這個操作呢?
動態代理
拓展接口如下 CarInterfaces.class:
interface CarInterfaces {
void run();
void playMusic();
void stop();
}
目標類實現接口 Car.class:
public class Car implements CarInterfaces {
@Override
public void run() {
System.out.println("Car run()");
}
@Override
public void playMusic() {
System.out.println("Car playMusic()");
}
@Override
public void stop() {
System.out.println("stop()");
}
}
代理類 動態代理接口 CarSystemProxy.class:
public class CarSystemProxy {
Car car;
public Object getProxy() {
if (car == null) {
car = new Car();
}
return Proxy
.newProxyInstance(getClass().getClassLoader(), car.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("find proxy.... ");
Object invoke = method.invoke(car, args);
return invoke;
}
});
}
}
測試類 CarTest.class:
public class CarTest {
public static void main(String[] args) {
CarSystemProxy carSystemProxy = new CarSystemProxy();
CarInterfaces proxy = (CarInterfaces) carSystemProxy.getProxy();
proxy.run();
proxy.playMusic();
proxy.stop();
}
}