Java反射與 JDK代理調用

    最近由於項目須要溫習Spring的時候,看到有一章節講的是JDK代理調用,因此就結合公司的Invoke代理調用再一次看了一遍代理這一塊。java

    1、反射

    一般java中都是由java類編譯成class文件,即先有類再有對象,那麼有了對象以後咱們就能夠調用對象的方法和屬性。可是經過反射咱們能夠經過Class對象來調用類裏面的方法。經過反射能夠調用私有方法和私有屬性。大部分框架都是運用反射原理。spring

    這是獲取class對象的三種方式編程

//一、經過對象調用 getClass() 方法來獲取,一般應用在:好比你傳過來一個 Object
 //  類型的對象,而我不知道你具體是什麼類,用這種方法
   Person p1 = new Person();
   Class c1 = p1.getClass();
         
 //二、直接經過 類名.class 的方式獲得,該方法最爲安全可靠,程序性能更高
 //  這說明任何一個類都有一個隱含的靜態成員變量 class
    Class c2 = Person.class;
         
 //三、經過 Class 對象的 forName() 靜態方法來獲取,用的最多,
 //   但可能拋出 ClassNotFoundException 異常
   Class c3 = Class.forName("com.ys.reflex.Person");

2、動態代理

    關於動態代理和靜態代理 當一個對象(客戶端)不能或者不想直接引用另外一個對象(目標對象),這時能夠應用代理模式在這二者之間構建一個橋樑--代理對象。 按照代理對象的建立時期不一樣,能夠分爲兩種: 靜態代理:事先寫好代理對象類,在程序發佈前就已經存在了; 動態代理:應用程序發佈後,經過動態建立代理對象。安全

    動態代理:應用程序發佈後,經過動態建立代理對象。框架

3、JDK動態代理

    JDK動態代理只能針對實現了接口的類生成代理性能

public Object newProxy(Object targetObject) {// 將目標對象傳入進行代理 
    this.targetObject = targetObject;  <br>    //注意這個方法的參數,後面是實現類實現的接口
    return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), 
            targetObject.getClass().getInterfaces(), this);// 返回代理對象

在上面的代碼中,咱們知道,jdk傳入的實際上是實現類所實現的接口 flex

targetObject.getClass().getInterfaces(), 因此jdk動態代理只能對接口Interface進行代理。this

4、動態代理的應用spa

   動態代理還有一種是Cglib,是實現不是接口的類的動態代理。代理

    AOP(Aspect-OrientedProgramming,面向切面編程),AOP包括切面(aspect)、通知(advice)、鏈接點(joinpoint),實現方式就是經過對目標對象的代理在鏈接點先後加入通知,完成統一的切面操做。

實現AOP的技術,主要分爲兩大類:

一是採用動態代理技術,利用截取消息的方式,對該消息進行裝飾,以取代原有對象行爲的執行;

二是採用靜態織入的方式,引入特定的語法建立「方面」,從而使得編譯器能夠在編譯期間織入有關「方面」的代碼。

Spring提供了兩種方式來生成代理對象: JDKProxy和Cglib,具體使用哪一種方式生成由AopProxyFactory根據AdvisedSupport對象的配置來決定。

默認的策略是若是目標類是接口,則使用JDK動態代理技術,若是目標對象沒有實現接口,則默認會採用CGLIB代理。

若是目標對象實現了接口,能夠強制使用CGLIB實現代理(添加CGLIB庫,並在spring配置中加入<aop:aspectj-autoproxy proxy-target-class="true"/>)。

相關文章
相關標籤/搜索