java代理模式

來源:互聯網
上載者:User

標籤:linked   link   ima   個性   default   nts   getname   導致   缺點   

引言

我們在寫一個功能函數的時候,常常要寫入一些與功能無關的代碼,如日誌記錄、參數校正、安全和事務支援等。功能無關代碼混在函數中,會帶來一些麻煩

  • 對OO造成破壞
  • 加深類之間的耦合
  • 代碼重用性降低

代理模式可以解決這個問題,關鍵功能代碼放在函數中,枝節性代碼放在代理類中

代理模式

1、作用

代理模式的作用是,為其他對象提供一種代理,在不改變介面的前提下,以控制對這個對象的訪問

2、角色

代理模式一般涉及到3個角色:抽象角色(介面)、代理角色、真實(被代理)角色

3、類型

靜態代理、動態代理(jdk代理、CGLIB代理)

靜態代理

代理類、被代理類需要實現相同的介面,或者繼承相同的父類

/** * Created by danny.yao on 2017/10/9. * 靜態代理中,代理類和被代理類需要實現此介面 */public interface IUser {    public void doSomething(String thingsToDo);} /** * Created by danny.yao on 2017/10/9. * 被代理類,真實商務邏輯 */public class Danny implements IUser {    public void doSomething(String thingsToDo) {        System.out.println(this.getClass().getName() + "一邊唱歌一邊" + thingsToDo);    }} /** * Created by danny.yao on 2017/10/9. * 代理類,被代理類作為其屬性,增強被代理類功能 */public class UserProxy implements IUser {    private IUser user;    public UserProxy(IUser user){        this.user = user;    }    // 在不改變danny行為的基礎上,增強功能    public void doSomething(String thingsToDo) {        doBefore();        user.doSomething(thingsToDo);        doAfter();    }    private void doBefore(){        System.out.println("賴床。。。");        System.out.println("起床洗漱。。。");        System.out.println("吃早飯。。。");        System.out.println("然後。。。");    }    private void doAfter(){        System.out.println("那啥之後。。。");        System.out.println("開始打王者榮耀!");    }}

測試類別

public class UserProxyTest {    @Test    public void testDoSomething(){        UserProxy dannyProxy = new UserProxy(new Danny());        dannyProxy.doSomething("上班!!");    }}

缺點:

  • 被代理類須已經存在,而且作為代理類的內部屬性
  • 每個業務類都要一個代理類,如果業務量龐大,會導致類急劇膨脹
動態代理

動態代理類的源碼是在程式運行期間,由JVM根據反射等機制動態產生的

1、jdk代理

被代理類,須實現介面;代理類,不需要實現介面

// 介面和實作類別,同靜態代理 public class DynamicProxy implements InvocationHandler {    // 把靜態代理中的類引用,改為Object類型    private Object object;    public DynamicProxy(Object object){        this.object = object;    }    // 把方法調用過程改為反射方式,不依賴介面的具體方法    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        doBefore();        method.invoke(object, args);        doAfter();        return null;    }    private void doBefore(){        System.out.println("那啥之前。。。");    }    private void doAfter(){        System.out.println("那啥之後。。。");    }    // 返回動態代理 newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)    public <T> T getProxy(){        return (T) Proxy.newProxyInstance(              object.getClass().getClassLoader(),                object.getClass().getInterfaces(),                this        );    }}

測試類別

public class DynamicProxyTest {    @Test    public void testInvoke() throws Exception {        DynamicProxy dynamicProxy = new DynamicProxy(new Danny());        IUser dannyProxy = dynamicProxy.getProxy();        dannyProxy.doSomething("上班!!");    }}

缺點:

  • 被代理類必須實現介面
2、CGLIB代理

也叫作子類代理,它是在記憶體中構建一個子類對象,從而實現對目標對象功能的擴充。被代理類不需要實現介面

// 未實現介面的類public class Pig {    public void doSomething(String thingsToDo){        System.out.println("懶洋洋地" + thingsToDo);    }} public class CGLibProxy implements MethodInterceptor {    public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {        doBefore();        Object result = methodProxy.invokeSuper(o, args);        doAfter();        return result;    }    // cglib 中通過加強器來建立代理    public <T> T getProxy(Class<T> tClass){        return (T) Enhancer.create(tClass, this);    }    private void doBefore(){        System.out.println("那啥之前。。。");    }    private void doAfter(){        System.out.println("那啥之後。。。");    }}

測試類別

public class CGLibProxyTest {    @Test    public void testIntercept() throws Exception {        CGLibProxy cgLibProxy = new CGLibProxy();        Pig pigProxy = cgLibProxy.getProxy(Pig.class);        pigProxy.doSomething("思考人生。。。");    }}

缺點:

  • 會攔截並封裝被代理類的所有方法,做不到方法層級的個人化攔截

參考:

https://www.zhihu.com/question/20794107

http://www.cnblogs.com/machine/archive/2013/02/21/2921345.html

http://www.cnblogs.com/cenyu/p/6289209.html

java代理模式

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.