<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      (轉)Java動態代理與CGLib代理

      本文通過spring aop的代理實現簡述了java動態代理和cglib的區別,有助于理解java的代理模式
       
      Java代碼  
      1. <br>public class UserDAOImpl{  
      2. <br><br>    public void save() {  
      3. <br>        // TODO Auto-generated method stub  
      4. <br>        System.out.println("user saved");  
      5. <br>    }  
      6. <br>}  
      7. <br>//相關配置,省略了一些不相關內容  
      8. <br><bean id="userDAO" class="UserDAOImpl">  
      9. <br><bean id="userDAOProxy"  class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">   
      10. <br>    <property name="target">   
      11. <br>        <ref local="userDAO" />   
      12. <br>    </property>   
      13. <br></bean>  

         測試代碼

      Java代碼  
      1.         ApplicationContext ctx =  
      2. <br>            new FileSystemXmlApplicationContext("applicationContext.xml");  
      3. <br>        UserDAOImpl userDAOImpl =   
      4. <br>            (UserDAOImpl)ctx.getBean("userDAOProxy");  
      5. <br>        userDAOImpl.save();  

         上面這種情況下程序可以正常運行,但是如果UserDAOImpl實現了一個接口,其他不變

      Java代碼  
      1. public class UserDAOImpl implements UserDAO {  
      2. <br>  
      3. <br>    public void save() {  
      4. <br>        // TODO Auto-generated method stub  
      5. <br>        System.out.println("user saved");  
      6. <br>    }  
      7. <br>  
      8. <br>}  

       這種情況下,程序將不能正常運行,會拋出java.lang.ClassCastException異常

      理解上面這種情況產生的原因需要了解Spring AOP的實現原理。
      Spring 實現AOP是依賴JDK動態代理和CGLIB代理實現的。
      以下是JDK動態代理和CGLIB代理簡單介紹
          JDK動態代理:其代理對象必須是某個接口的實現,它是通過在運行期間創建一個接口的實現類來完成對目標對象的代理。
          CGLIB代理:實現原理類似于JDK動態代理,只是它在運行期間生成的代理對象是針對目標類擴展的子類。CGLIB是高效的代碼生成包,底層是依靠ASM(開源的java字節碼編輯類庫)操作字節碼實現的,性能比JDK強。
      Spring是依靠什么來判斷采用哪種代理策略來生成AOP代理呢?以下代碼就是Spring的判斷邏輯

      Java代碼  
      1.     //org.springframework.aop.framework.DefaultAopProxyFactory  
      2. <br>    //參數AdvisedSupport 是Spring AOP配置相關類  
      3. <br>    public AopProxy createAopProxy(AdvisedSupport advisedSupport)  
      4. <br>            throws AopConfigException {  
      5. <br>        //在此判斷使用JDK動態代理還是CGLIB代理  
      6. <br>        if (advisedSupport.isOptimize() || advisedSupport.isProxyTargetClass()  
      7. <br>                || hasNoUserSuppliedProxyInterfaces(advisedSupport)) {  
      8. <br>            if (!cglibAvailable) {  
      9. <br>                throw new AopConfigException(  
      10. <br>                        "Cannot proxy target class because CGLIB2 is not available. "  
      11. <br>                                + "Add CGLIB to the class path or specify proxy interfaces.");  
      12. <br>            }  
      13. <br>            return CglibProxyFactory.createCglibProxy(advisedSupport);  
      14. <br>        } else {  
      15. <br>            return new JdkDynamicAopProxy(advisedSupport);  
      16. <br>        }  
      17. <br>    }  

       

       

       

       

       

               advisedSupport.isOptimize()與advisedSupport.isProxyTargetClass()默認返回都是false,所以在默認情況下目標對象有沒有實現接口決定著Spring采取的策略,當然可以設置advisedSupport.isOptimize()或者advisedSupport.isProxyTargetClass()返回為true,這樣無論目標對象有沒有實現接口Spring都會選擇使用CGLIB代理。所以在默認情況下,如果一個目標對象如果實現了接口Spring則會選擇JDK動態代理策略動態的創建一個接口實現類(動態代理類)來代理目標對象,可以通俗的理解這個動態代理類是目標對象的另外一個版本,所以這兩者之間在強制轉換的時候會拋出j ava.lang.ClassCastException。而所以在默認情況下,如果目標對象沒有實現任何接口,Spring會選擇CGLIB代理, 其生成的動態代理對象是目標類的子類。

       

       

         

           以上說的是默認情況下,也可以手動配置一些選項使Spring采用CGLIB代理。

      org.springframework.transaction.interceptor.TransactionProxyFactoryBean是org.springframework.aop.framework. ProxyConfig的子類,所以可以參照ProxyConfig里的一些設置如下所示,將optimize和proxyTargetClass任意一個設置為true都可以強制Spring采用CGLIB代理。

      Java代碼  
      1. //相關配置,省略了一些不相關內容  
      2. <br><bean id="userDAO" class="UserDAOImpl">  
      3. <br><bean id="userDAOProxy"  class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">   
      4. <br>    <property name="target">   
      5. <br>        <ref local="userDAO" />   
      6. <br>    </property>   
      7. <br>    <property name="optimize">   
      8. <br>        <value>true</value>  
      9. <br>    </property>  
      10. <br>    <property name="proxyTargetClass">   
      11. <br>        <value>true</value>  
      12. <br>    </property>   
      13. <br></bean>  

       

       

      使用CGLIB代理也就不會出現前面提到的ClassCastException問題了,

      也可以在性能上有所提高,但是也有它的弊端,Spring doc原文解釋如下optimization will usually mean that advice changes won't take effect after a proxy has been created. For this reason, optimization  is disabled by default。

      posted @ 2014-06-19 14:57  懶惰的肥兔  閱讀(2430)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 精品国偷自产在线视频99| 中文字幕有码日韩精品| 亚洲成人资源在线观看| 国产一区在线观看不卡| 猫咪AV成人永久网站在线观看| 人妻少妇456在线视频| 亚洲熟女乱色综一区二区| 在线天堂最新版资源| 国产精品亚洲а∨天堂2021| 成人精品视频一区二区三区| 中文字幕乱码中文乱码毛片| 97免费人妻在线视频| 中文在线а√天堂| 精品九九人人做人人爱| 淮阳县| 亚洲欧美激情在线一区| 亚洲欧美精品在线| 在线中文字幕国产一区| 天堂va欧美ⅴa亚洲va在线| 亚洲一区二区三区| 国产一区二区日韩经典| 丰满人妻一区二区三区色| 国产精品人成视频免| 国产男女黄视频在线观看| 高潮潮喷奶水飞溅视频无码| 马公市| 国产日产欧产系列| 天堂v亚洲国产v第一次| 亚洲第一区二区国产精品| 久久狠狠高潮亚洲精品| 国产无遮挡真人免费视频| 久久精品无码一区二区小草| 人妻av无码系列一区二区三区| 精品亚洲欧美高清不卡高清| 少妇高潮太爽了在线视频| 精品乱人伦一区二区三区| 亚洲精品一区二区三区蜜| 少妇伦子伦精品无吗| 亚洲区日韩精品中文字幕| 福利一区二区1000| 精品一区二区亚洲国产|