代理模式之JDK的動態代理
阿新 • • 發佈:2018-12-18
JDK的動態代理比較簡單,是內建在JDK中的,不需要引入第三方jar包,但相對其他代理它的功能就比較弱了。
下面就以demo為例來學習它。分為延遲載入demo和安全作用的demo
延遲載入demo
主題介面: 定義代理類和真實主題的公共對外方法
/**
* 主題介面
*/
public interface IDBQuery {
String request();
}
真實主題:
public class DBQuery implements IDBQuery { public DBQuery() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("真實被建立"); } @Override public String request() { return "我是真實的"; } }
代理類:用來代理和封裝真實主題,代理真實主題的位置,加快系統啟動速度
/** * 代理角色 */ public class DBQueryDelayProxy implements InvocationHandler { private IDBQuery real = null; public DBQueryDelayProxy() { System.out.println("代理被建立"); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if(real == null) { real = new DBQuery(); } return real.request(); } }
客戶端:
@Test
public void jdkDelayProxyTest() {
IDBQuery jdkProxy = (IDBQuery) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),new Class[] {IDBQuery.class},
new DBQueryDelayProxy());
jdkProxy.request();
}
中間層作用demo(安全)
主題介面:是定義代理類和真實主題的公共對外方法
public interface JDKInterface {
/**
* 出售房
*/
void sell();
/**
* 和租客碰面
*/
void contact();
/**
* 收費
*/
void charge();
}
真實主題:是真正實現業務邏輯的類
public class JDKHouseOwner implements JDKInterface {
@Override
public void sell() {
System.out.println("售賣的相關事");
}
@Override
public void contact() {
System.out.println("碰面");
}
@Override
public void charge() {
System.out.println("房屋出租價格範圍");
}
}
代理類: 用來代理和封裝真實主題,可以起到保護真實主題的作用,也可以做延遲載入。本次以安全作用為例:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class JDKIntermediary implements InvocationHandler {
private JDKInterface real;
public JDKIntermediary(JDKInterface real) {
this.real = real;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
method.invoke(real,args);
return null;
}
}
客戶端:
@Test
public void jdkProxyTest() {
JDKInterface real = new JDKHouseOwner();
InvocationHandler invocationHandler = new JDKIntermediary(real);
JDKInterface jdkInterface = (JDKInterface) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),new Class[] {JDKInterface.class},
invocationHandler);
jdkInterface.sell();
jdkInterface.contact();
jdkInterface.charge();
}
代理類的內部邏輯是用JDKIntermediary決定的。生成代理後,由 Proxy.newProxyInstance()返回一個代理類的例項。
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
loader: the class loader to define the proxy class
interfaces: the list of interfaces for the proxy class to implement
h: the invocation handler to dispatch method invocations to