天天看點

Java反射學習總結三(靜态代理)

反射最常見的應用就是代理模式了。

本文先簡單介紹一下代理模式,并寫一個靜态代理的例子。為下一篇重要的動态代理做點鋪墊

代理模式的作用是:

為其他對象提供一種代理以控制對這個對象的通路。

另外在某些情況下,一個客戶不想或着不能直接引用另一個對象,而代理對象可以在用戶端和目标對象之間起到中介的作用。

說白了,代理模式就是一個"中介",他有這客戶們的引用,是以可以用這個"中介"來代替客戶來做操作。

代理模式設計的角色:

想使用代理模式,需要定義如下的3個角色:

抽象角色:

聲明真實對象和代理對象的共同接口

真實對象:

代理角色所代表的真實對象,是我們最終要引用的對象

代理角色: 

1.代理對象内部含有對真實對象的引用,進而可以操作真實的對象。

2.代理對象提供與真實對象相同的接口以便在任何時刻都能代替真實對象。

3.代理對象可以在執行真實對象操作時,附加其他的操作,相當于對真實對象進行封裝

可能看完概念後有點迷糊,接下來直接上代碼看例子應該會比較容易了解:

1.首先定義抽象角色對象,使用抽象類或者接口來定義一個代理角色和真實對象共有的一個方法。這個方法就是被代理角色委托給"中介"來操作的方法

[java] view plain copy print?

//這裡定義一個抽象類  

public abstract class Subject {  

    //空的抽象方法,這個方法需要代理角色和真實角色都去實作它  

    public abstract void request();  

}  

2.定義真實角色對象

//真實角色對象,繼承自抽象角色,重寫定義的方法。  

public class RealSubject extends Subject{  

    //在重寫的方法中實作需要的操作,這裡隻是簡單列印一句  

    @Override  

    public void request() {  

        System.out.println("this is real subject");  

    }  

3.定義代理角色對象

//代理角色,同樣繼承抽象角色,重寫抽象角色中的方法  

public class ProxySubject extends Subject{  

    //在代理角色内部對真實角色的引用  

    private RealSubject realSubject;      

    //重寫的實作抽象角色中的方法  

        this.preRequest();  //在調用真實角色操作之前所附加的操作  

        if (realSubject == null) {  

            realSubject = new RealSubject();  

        }  

        realSubject.request();  //真實角色所完成的事情  

        this.postRequest();  //在真實角色操作之後所附加的操作  

    //自定義的方法,在真實方法執行之前調用的方法  

    private void preRequest() {  

        System.out.println("pre request");  

    //自定義的方法,在真實方法執行之後調用的方法  

    private void postRequest() {  

        System.out.println("post request");  

在實作代理角色對象時,最重要的一點是要有一個真實對象的引用。

通過這個引用在代理對象中去調用真實對象的方法,并且可以自定義一些其他的操作,比如本例子中的preRequest()和postRequest(),他們分别在之前和之後被調用。

這樣做可以記錄一下運作時間或打log之類的操作,但這裡僅僅是列印了一句話。

4.最後看看main方法中如何調用:

public class TestProxy {  

    public static void main(String[] args) {  

        //執行個體化一個代理角色對象  

        Subject subject = new ProxySubject();  

        //用代理對象去調用定義的通用方法  

        subject.request();  

輸出為:

pre request

this is real subject

post request

大家看代碼後可以發現,這裡并沒有用到反射的知識。而且對于上面的例子來說,真實角色對象是事先必須已經存在的,并且必須是作為代理對象的内部屬性。

如果這樣的話,有一個真實角色那就必須在代理角色中有一個他的引用,如果在不知道真實角色的情況下又需要怎麼辦?這就需要"動态代理"來解決了。

下一篇文章就來介紹"動态代理"。