1. 程式人生 > >JDK的動態代理技術(JDK proxy)

JDK的動態代理技術(JDK proxy)

我們先說怎麼實現JDK為我們提供的動態代理。(這篇文章目的是為Spring框架中的AOP思想提供技術支援

0.用到反射包下的類,以及InvocationHandler介面。

需要寫自己的實現類。

問題1:為什麼一定要實現這個介面?

1.自定義工廠類,以JDkProxyFactor為自己的工廠類。

程式碼如下:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class JDkProxyFactory implements InvocationHandler{

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		return null;
	}

}

2.寫自己的業務邏輯。

關於方法的引數的說明:

proxy--為誰產生代理

Method--為哪個方法產生代理

Args--這個方法需要哪些引數

程式碼結構圖如下:

我就為Dog介面產生代理。

Dog介面有void bark()方法。

物件我不用他提供的Object proxy,我自己通過構造器注入一個。(沒有註釋請見諒)

private Object target; 
    public JDKProxyFactory(Object target) {  
        super();  
        this.target = target;  
    }  

--------------------------------------------------------------------------------------------關鍵的一步到了------------------------------------

真理總是很簡單,但人們卻常常很難發現它。

我要做什麼?為什麼一定要這樣做?為了AOP思想。

AOP思想是個神馬玩意兒?是不改原來的程式碼但是又可以新增程式碼的神奇技術。

因此,我們需要在原來的類的基礎上再克隆一個類,但是這個類寫我們要新增的程式碼,然後執行的是這個類而不是原來的類。

我要產生這樣一個位元組碼物件,更具體(在此文),我要產生Dog介面的物件,通過多型建立他子類哈士奇HashiQI的物件。

HaShiQi類:

package com.gzz.review;

public class HaShiQi implements Dog{

	@Override
	public void bark() {
		System.out.println("主人給我骨頭");
	}
	
	public void play() {
		System.out.println("主人陪我玩");
	}

}

怎麼產生?

自己定義了一個方法用於得到我想要的類的物件。

提示需要一個classloader和一個介面和一個InvocationHandler。

通過讀取當前執行緒的類的上下文獲得classloader,讓它去載入這個類

程式碼如下:

Thread.currentThread().getContextClassLoader()

 還需要一個介面

通過查API,我知道了,interfaces - 代理類要實現的介面列表

還記得我們通過構造器傳過來的那個代理物件,那個物件在被建立的時候肯定是由多型建立了,其實那個物件是介面的實現類哈士奇物件。所以我們要得到那個介面,Dog。

同樣的,在反射包下提供了獲得介面的辦法。

程式碼如下:

target.getClass().getInterfaces()

還需要一個引數,InvocationHadler。直接傳this。因為這個JDkProxyFactory類實現了InvocationHadler介面。

我們就湊夠了這個引數。

這樣,就獲得了那個類的物件。

然後搞測試。

建立一個測試類,就叫TestDog吧。

程式碼如下:

package com.gzz.review;

public class TestDog {

	public static void main(String[] args) {
		Dog dog = new HaShiQi();
		JDkProxyFactory jDkProxyFactory = new JDkProxyFactory(dog);
		Dog hashiqi = (Dog) jDkProxyFactory.getProxy();
		hashiqi.bark();
	}
}

這樣我們就用JDK的方式實現了AOP思想。JDK動態代理技術的實現到此為止。

對了,還有問題一:我們可以寫自己的實現AOP的類,但必須實現InvocationHandler這個介面,就像寫Servlet就必須遵循sun公司幫我們制定好的xsd約束。這是一種規範,規範就必須遵循的。

值得說明,這種自己實現的技術有侷限,侷限是不能得到實現類的私有方法。本例中HaShiQi類的void play()方法就沒有拿到。