真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

大數(shù)據(jù)開發(fā)中動態(tài)代理是什么

這篇文章主要介紹了大數(shù)據(jù)開發(fā)中動態(tài)代理是什么,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

創(chuàng)新互聯(lián)堅持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:做網(wǎng)站、網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時代的烏海海南網(wǎng)站設(shè)計、移動媒體設(shè)計的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!

一、動態(tài)代理的意義

 首先明白一點,動態(tài)代理就是用來生成代理對象的。我們知道傳統(tǒng)的代理模式,通常是先定義一個代理類,該代理類需要持有目標對象(也有叫被代理對象,我覺得都行吧)。假設(shè)我們有1000個不同的目標對象(這1000個對象不是同一個類),那么我們需要預(yù)先定義1000個代理類,這是我們不能容忍的。于是乎,動態(tài)代理就出現(xiàn)了,它本質(zhì)上是生成一個外表上和目標對象一樣的代理對象,然后當(dāng)我們調(diào)用代理對象的方法的時候,實際上它在他的方法里面去調(diào)用了目標對象對應(yīng)的同名方法。

二、動態(tài)代理設(shè)計的核心思想

其實不要把這些設(shè)計想得多么高尚,假如我是動態(tài)代理設(shè)計的作者,由動態(tài)代理的意義部分我們知道,我們就是要想盡一切辦法,通過目標對象生成代理對象,然后讓代理對象的方法調(diào)用作用到目標對象的方法調(diào)用。沒錯動態(tài)代理的核心思想就是這么簡單。比如目標類為Person,Person有一個方法叫做purchase(),此方法用于購物。我們期望purchase()方法有代理類去做處理,比如在購物前記錄下購買了哪些東西。我們知道在使用一個類之前,是需要創(chuàng)建一個對象的,我們就在創(chuàng)建的地方動手腳。所以你看到了JDK動態(tài)Proxy.newInstance()的方式,也領(lǐng)略過Spring的Enhancer.create()。個人比較喜歡cglib的優(yōu)雅、干凈、利落。吐槽一下JDK的InvocationHandler像極了惡心的中間商。下面是JDK動態(tài)代理UML示意圖

大數(shù)據(jù)開發(fā)中動態(tài)代理是什么

三、JDK動態(tài)代理

1,原理

在了解動態(tài)代理之前,我們需要了解Java字節(jié)碼。如果不熟悉Java字節(jié)碼,你可以理解為通過代碼動態(tài)生成一個.java文件,然后將其編譯為class文件加載到內(nèi)存中。接下來JDK中的動態(tài)代理要做的事情就是怎么去生成一個ProxyPerson字節(jié)碼文件。其實它就是在生成字節(jié)碼的時候,持有了InvocationHandler對象,然后去實現(xiàn)了ProxyPerson對應(yīng)的接口。在該接口的所有實現(xiàn)方法中,只做了一件事情就是調(diào)用invocationHandler.invoke()方法。從代碼層面來看如下所示:

public class ProxyPerson implements Purchase{

static{   Method method;// 接口的方法   Object[] args;// 接口參數(shù)  }
InvocationHandler handler;public ProxyPerson(InvocationHandler handler){    this.handler = handler;}

@overrdepublic purchage(){   this,handler.invoke(this,method,args);  }
}

 那么上面這段代碼是在什么時候生成的呢? 

Proxy.newProxyInstance()

在我們調(diào)用JDK上面的這個方法的時候,底層就會去生成一個ProxyPerson字節(jié)碼。知道了原理我們來解答一下JDK動態(tài)代理為何只能基于接口代理而不能基于類呢?

1),受限于字節(jié)碼的生成方式,JDK本身就是基于InvocationHandler去做的代理中轉(zhuǎn)。我們看到代理對象的方法調(diào)用于目標對象的調(diào)用沒有半毛球關(guān)系,調(diào)用目標對象是我們自己在invoke方法里面完成的。

2),受限于同名的方法只能被向上轉(zhuǎn)型成功的對象調(diào)用。比如有兩個類Boy與Girl,他們都實現(xiàn)了接口Purchase,如果我們先獲取到Girl的purchase()方法method,我們通過method.invoke(new Boy())這樣必定會報錯。但是如果我們獲取到Purchase接口purchase()方法method,我們通過method.invoke(new Boy())這樣是ok的,因為new Boy()可以向上轉(zhuǎn)型為Purchase。

2,應(yīng)用

比如無論是傳統(tǒng)的MVC模型還是DDD模型,都離不開Service。我們知道Service方法使用@Transactional是可以開啟事務(wù)控制的。那么這種注解式事務(wù)是如何實現(xiàn)的呢?其實在工程啟動的時候,我們就會有一個Bean的后置處理器去檢查所有Bean一旦發(fā)現(xiàn)Bean的方法上有事務(wù)注解,他就通過Proxy.newInstance()去創(chuàng)建一個代理對象,將代理對象進行返回注入,而拋棄原本應(yīng)該注入到容器的對象。所以我們看起來通過容器拿到的Service其實已經(jīng)是代理對象了。在調(diào)用目標對象前,開啟編程式事務(wù)即可。

四、cglib動態(tài)代理

 有了上面的知識,我們要有對于cglib而言只是在生成字節(jié)碼上面動手腳的覺悟。下面直觀感受與一下生成過程

public static void main(final String[] args) {        Enhancer enhancer = new Enhancer();       enhancer.setSuperclass(Boy.class);       enhancer.setCallback(new MethodInterceptor(){            @Override           public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {               System.out.println("proxy method "+ method.getName());               if(method.getAnnotation(Transactional.class)!=null){                   System.out.println(method.getName()+"發(fā)現(xiàn)注解");               }               return methodProxy.invokeSuper(o,args);           }       });       Boy proxy = (Boy) enhancer.create();       proxy.test();     }    public static class Boy{       public void run(){           System.out.println("run...");       }       @Transactional       public void walk(){           System.out.println("walk...");       }       @Transactional       public void test(){           System.out.println("test...");           walk();       }   }

可以看到cglib是基于繼承的方式進行字節(jié)碼動態(tài)生成。 它在子類的實現(xiàn)中,只是調(diào)用了注入的methodIntercptor.interceptor()方法。 具體字節(jié)碼實現(xiàn)細節(jié),這里不在深究。 我們在這里探討一下,為什么cglib可以使同一個service方法中的其他帶有事務(wù)注解的事務(wù)生效?因為基于繼承的動態(tài)代理,本質(zhì)發(fā)起上調(diào)用的代理對象可以向上轉(zhuǎn)型為原本的目標對象,所以它可以直接通過代理對象去調(diào)目標對象方法。  

感謝你能夠認真閱讀完這篇文章,希望小編分享的“大數(shù)據(jù)開發(fā)中動態(tài)代理是什么”這篇文章對大家有幫助,同時也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關(guān)知識等著你來學(xué)習(xí)!


分享文章:大數(shù)據(jù)開發(fā)中動態(tài)代理是什么
文章起源:http://weahome.cn/article/ggchcd.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部