本文面向初接觸動態代理的學者,代碼貼在最後
靜態代理
其實現思路:
從前有A,B商家註冊到了C平臺上,A提供一些初級的服務,B對A的服務進行了一些封裝從而能實現更厲害的服務。
(寫到這裏我突然發現和SpringCloud咋這麼像。。。。。)
其映射在Java中就是:
C是一個接口,A,B都實現了該接口,B中持有A的引用,B調用方法都是通過A來實現,只不過在實現前後增加了一些操作。
(和裝飾者模式咋這麼像。。。。。)
其實雖然實現方式是差不多的,但是其終究目的卻不同:裝飾着模式是增強方法而靜態代理是保護和隱藏被代理對象
動態代理
實現思路:
同樣有C平臺和A,B商家。同樣是A提供一些初級的服務,B對A的服務進行了一些封裝從而能實現更厲害的服務。差別就在B對A提供的散裝服務不用一個一個處理了,而是一起處理
其體現在Java代碼中是這樣的:
對於B類,不用去實現C接口了,而是持有一個實現C接口的A類引用(在B中要用Object,不然要轉換十分麻煩,但是在調用的時候卻要傳入一個A類的引用),自己實現InvocationHandler接口,其就是jdk爲我們提供的動態生成代碼的方式:
在以下代碼中:C ==Dormitory,B == DormitoryProxy(靜態),DynamicDormitory(動態),A==MyDormitory
package sjms.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* @Author Yan1less
* @Date 2019/5/1 15:22
* @Description TODO
**/
public class DynamicProxy implements InvocationHandler {
// 這個就是我們要代理的真實對象
private Object subject;
// 構造方法,給我們要代理的真實對象賦初值
public DynamicProxy(Object subject)
{
this.subject = subject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 在代理真實對象前我們可以添加一些自己的操作
System.out.println("使用方法之前");
System.out.println("Method:" + method);
// 當代理對象調用真實對象的方法時,其會自動的跳轉到代理對象關聯的handler對象的invoke方法來進行調用
Object invoke = method.invoke(subject, args);
// 在代理真實對象後我們也可以添加一些自己的操作
System.out.println("使用方法之後");
return invoke;
}
}
package sjms.proxy;
/**
* @Author Yan1less
* @Date 2019/5/1 14:53
* @Description 被代理類,靜態代理其實和裝飾這模式有點像,這其實可以類比成被裝飾者
**/
public class MyDormitory implements Dormitory{
@Override
public void OneFloor() {
System.out.println("這裏是一層");
}
@Override
public void TwoFloor() {
System.out.println("這裏是二層");
}
@Override
public void ThreeFloor() {
System.out.println("這裏是三層");
}
@Override
public int FourFloor() {
System.out.println("這裏是四層");
return 8888;
}
}
package sjms.proxy;
/**
* @Author Yan1less
* @Date 2019/5/1 14:53
* @Description 可以類比成裝置這模式中的裝飾者,不過其較動態代理麻煩的地方在於:
* 1.方法都要重寫一遍,有點麻煩
* 2.構造方法傳參需要類型轉化
* 最大的區別還是在與:裝飾者模式主要目的是增強方法,靜態代理目的是保護與隱藏被代理對象
**/
public class DormitoryProxy implements Dormitory{
private MyDormitory myDormitory;
public DormitoryProxy(Dormitory dormitory) {
if(dormitory.getClass() == MyDormitory.class){
myDormitory = (MyDormitory)dormitory;
}
}
@Override
public void OneFloor() {
System.out.println("抵達XX公寓");
myDormitory.OneFloor();
}
@Override
public void TwoFloor() {
System.out.println("抵達XX公寓");
myDormitory.TwoFloor();
}
@Override
public void ThreeFloor() {
System.out.println("抵達XX公寓");
myDormitory.ThreeFloor();
}
@Override
public int FourFloor() {
System.out.println("抵達XX公寓");
myDormitory.FourFloor();
return 8888;
}
}
package sjms.proxy;
/**
* @Author Yan1less
* @Date 2019/5/1 14:52
* @Description 這是一個接口,被代理類和代理類都要實現它
**/
public interface Dormitory {
void OneFloor();
void TwoFloor();
void ThreeFloor();
int FourFloor();
}
package sjms.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @Author Yan1less
* @Date 2019/5/1 14:50
* @Description TODO
**/
public class Main {
public static void main(String[] args) {
Dormitory dormitory = new MyDormitory();
Dormitory proxy = new DormitoryProxy(dormitory);
proxy.OneFloor();
System.out.println("--------------------------------");
DynamicProxy dynamicProxy = new DynamicProxy(dormitory);
Dormitory a = (Dormitory)Proxy.newProxyInstance(dynamicProxy.getClass().getClassLoader(),
dormitory.getClass().getInterfaces(),dynamicProxy
);
int i = a.FourFloor();
System.out.println(i);
}
}