架構系列——java動態代理中的InvocationHandler和Proxy,知道這些已經妥妥的了

博主專注於Java、架構、Linux、小程序、爬蟲、自動化等技術。 工作期間含淚整理出一些資料,微信搜索【程序員高手之路】,回覆 【java】【黑客】【爬蟲】【小程序】【面試】等關鍵字免費獲取資料

前言

先贊後看,此生必賺!

Java中動態代理的實現,主要是InvocationHandler和Proxy的使用。

可以通過以下步驟實現一個動態代理:

一、創建正常的接口以及實現類

1. 接口:

public interface People {
	public void working();
}

2. 實現類:

public class Student implements People {
	
	@Override
	public void work() {
		System.out.println("正在學習...");
	}

}

二、創建一個PeopleHandler實現InvocationHandler

public class PeopleHandler implements InvocationHandler {
	private Object obj;
	
	public PeopleHandler(Object obj) {
		this.obj = obj;
	}

	public Object getProxy(Object obj) {
		return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
	}
	
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println("before invoke...");
		Object result = method.invoke(obj, args);
		System.out.println("after invoke...");
		return result;
	}

}

解讀:

PeopleHandler(Object obj):通過被代理對象創建handler;

getProxy(Object obj):通過被代理對象創建代理;

invoke(Object proxy, Method method, Object[] args):代理不直接調用invoke,而是使用正常的方法時都會走invoke方法;

三、調用方法

可以使用兩種方式調用方法:

1. 直接調用

不使用代理類直接調用,直接實現業務邏輯

2. 使用代理類調用

使用代理類調用,間接實現業務邏輯

public class TestProxy {
	public static void main(String[] args) {
		//1.直接調用
		System.out.println("直接調用:");
		People people = new Student();
		people.work();
		
		//2.通過代理調用
		System.out.println("\n通過代理調用:");
		PeopleHandler handler = new PeopleHandler(people);
		People proxy = (People) handler.getProxy(people);
		proxy.work();
	}
}

結果:

直接調用:
正在學習...

通過代理調用:
before invoke...
正在學習...
after invoke...

四、總結

1. 使用代理的好處

從上面的案例可以看出,兩者都可以實現正常的業務邏輯,那爲啥要多此一舉地使用代理類呢?

1.1 降低耦合度

正常邏輯work()日誌的關係沒那麼強烈,可以對業務邏輯的各個部分進行隔離。

1.2 提高可重用性

如果不使用代理,需要每一次在調用work()前後都要寫日誌,這樣的話,代碼的可重用性爲0!

使用代理之後,只需要在handler的invoke()方法中寫一次即可,重用性明顯提高!

2. 使用場景

除了上面案例中的日誌,還有性能統計,安全控制,事務處理,異常處理等等。

安全控制舉例

校驗用戶權限,每一個菜單請求,都要判斷一下請求的用戶是否有該菜單權限。菜單多了,代碼冗餘,且容易遺漏。

通過動態代理就可以實現爲:每一個用戶,每一個菜單的請求,都經過代理(proxy),由他判斷是否有權限,調用者只需要調用,實現自己的邏輯,不關心權限問題。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章