Java中的代理模式--靜態代理和動態代理

代理模式定義:爲其餘對象提供了一種代理以控制對這個對象的訪問。java

代理模式的三種角色:設計模式

  Subject抽象主題角色:抽象主題類能夠是抽象類也能夠是接口,是一個最普通的業務類型定義,無特殊要求。ide

  RealSubject具體主題角色:也叫作被委託角色、被代理角色。它纔是冤大頭,是業務邏輯的具體執行者,Subject接口的實現。學習

  Proxy代理主題角色:也叫作委託類、代理類。它負責對真實角色的應用,把全部抽象主題類定義的方法限制委託給真實主題角色實現,而且在真實主題角色處理完畢前作預處理和藹後工做。this

一句話描述靜態代理和動態代理:spa

  靜態代理:一個主題類與一個代理類一一對應。.net

  動態代理:多個主題類對應一個代理類。設計

靜態代理的例子:3d

 

 

Subject接口:代理

package com.design.one;
public interface Subject {
    void doSomething();
}

RealSubject類:

package com.design.one;
public class RealSubject implements Subject{
    @Override
    public void doSomething() {
        System.out.println("doSomething()......");
    }
} 

Proxy類:

package com.design.one;
public class Proxy implements Subject{
    Subject subject = null;
    public Proxy(Subject subject) {
        this.subject = subject;
    }
    @Override
    public void doSomething() {
        System.out.println("以前");
        subject.doSomething();
        System.out.println("以後");
    }
}

 Client類:

package com.design.one;
public class Client {
    public static void main(String[] args) {
        Subject sub = new RealSubject();
        Proxy proxy = new Proxy(sub);
        proxy.doSomething();
    }
}

輸出結果:

  以前
  doSomething()......
  以後

 

動態代理的例子:

引子:通常來講,使用靜態代理,都須要每個RealSubject編寫一一對應的代理類,這些類在編譯期間就已經肯定了的,若是有多個RealSubject類,可是他們的代理類裏面的前處理(「以前」)和後處理(「以後」)是同樣的,那麼使用靜態代理模式爲多個RealSubject類編寫相同的處理邏輯的代理類就顯得臃腫了和多餘了。而動態代理不一樣,它能使多個RealSubject類對應一個代理類,共享「前處理,後處理」功能,動態調用所需主題,大大減少了程序規模。

 

Subject類:

package com.design.three;
public interface Subject {
    void doSomething();
    void doSomething1();
} 

Subject2類:

package com.design.three;
public interface Subject2 {
    void doSomething3();
    void doSomething4();
} 

RealSubject類:

package com.design.three;
public class RealSubject implements Subject,Subject2{

    @Override
    public void doSomething() {
        System.out.println("doSomething()......");
    }
    @Override
    public void doSomething1() {
        System.out.println("doSomething()1......");  
    }
    @Override
    public void doSomething3() {
        System.out.println("doSomething()3......");
    }
    @Override
    public void doSomething4() {
        System.out.println("doSomething()4......");
    }
} 

RealSubject2類:

package com.design.three;
public class RealSubject2 implements Subject,Subject2{
    @Override
    public void doSomething() {
        System.out.println("Subject2doSomething()......");
    }
    @Override
    public void doSomething1() {
        System.out.println("Subject2doSomething()1......");   
    }
    @Override
    public void doSomething3() {
        System.out.println("Subject2doSomething()3......");
    }
    @Override
    public void doSomething4() {
        System.out.println("Subject2doSomething()4......");
    }
}

 MyInvocationHandler類:

package com.design.three;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyInvocationHandler implements InvocationHandler{
    private Object obj = null;
    public MyInvocationHandler(Object obj) {
        this.obj = obj;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        System.out.println("方法前....");
        return method.invoke(obj, args);
    }
}

 Client類:

package com.design.three;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class Client {
    public static void main(String[] args) {
        Subject sub = new RealSubject();//1
        // Subject sub = new RealSubject2();//2
        InvocationHandler handler = new MyInvocationHandler(sub);
        Subject proxy = (Subject) Proxy.newProxyInstance(sub.getClass()
                .getClassLoader(), sub.getClass().getInterfaces(), handler);
        proxy.doSomething();
    }
}

 輸出結果:

方法前....
doSomething()......

把2註釋打開,1註釋掉,輸出結果:

方法前....
Subject2doSomething()......

 

接下來是四篇我的認爲比較好的學習動態代理的文章,具體原理和分析都在下面了,我就再也不累贅了:

Java帝國之動態代理

動態代理和靜態代理到底有什麼區別,好處在哪裏?

JDK動態代理實現原理

Java設計模式——代理模式實現及原理

相關文章
相關標籤/搜索