<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 41,  comments - 8,  trackbacks - 0
    Java下的框架編程之cglib的應用
     

    Proxy可以看作是微型的AOP,明白提供了在繼承和委托之外的第三個代碼封裝途徑,只要有足夠的想象力,可以做得非常好玩,Spring的源碼里用Proxy就用得很隨便,看得我非常眼紅。可惜Proxy必須基于接口。因此Spring的做法,基于接口的用proxy,否則就用cglib。AOP么,一般小事非compoent一級的就不麻煩AspectJ出手了。

    cglib的Enhancer說起來神奇,用起來一頁紙不到就講完了。

    它的原理就是用Enhancer生成一個原有類的子類,并且設置好callback到proxy, 則原有類的每個方法調用都會轉為調用實現了MethodInterceptor接口的proxy的intercept() 函數:

                            

    public Object intercept(Object o,Method method,Object[] args,MethodProxy proxy)

    在intercept()函數里,你可以在執行Object result=proxy.invokeSuper(o,args);來執行原有函數,在執行前后加入自己的東西,改變它的參數值,也可以瞞天過海,完全干別的。說白了,就是AOP中的around advice。

    AOP沒有出現以前,該領域經典的設計模式是Decorator,像Java IO Stream的設計就是如此。不過,如果為每個DAO, 每個方法的寫Decorator函數會寫死人的,所以用上cglib的好處是一次過攔截所有方法。 

    另外,cglib除了Enhancer之外,還有BulkBean和Transform,都是Hibernate持久化的基礎,但文檔貧乏,一時還沒去看怎么用。

    1.AOP里講了一百遍啊一百遍的log aspect在cglib是這樣做的:

                            

    public class LogDAOProxy implements MethodInterceptor
       {
           
    private Logger log=Logger.getLogger(LogDAOProxy.class);
           
    private Enhancer enhancer=new Enhancer();
            
    //返回DAO的子類
           public Object getDAO(Class clz)
           {
               enhancer.setSuperclass(clz);
               enhancer.setCallback(
    this);
               
    return enhancer.create();
           }
           
    //默認的攔截方法
          public Object intercept(Object o,Method method,Object[] args,

    MethodProxy proxy) throws Throwable
          {
               log.info(
    "調用日志方法"+method.getName());
               Object result
    =proxy.invokeSuper(o,args);
               
    return result;
          }
       }


    應用的代碼:

                            

    LogDAOProxy proxy = new LogDAOProxy();
      GoodsDAO  dao 
    = (GoodsDAO)proxy.getDAO(GoodsDAO.class);
      dao.insert(goods);


    2.而在Spring的管理下應該略加修改的高級Decorator

    上面的例子用return enhancer.create();創建子類實例,但在Spring管理下,一些Bean的實例必須由Spring來創建和管理,而不由enhancer來創建的。所以我對上述用法略加修改,使它真正當一個Proxy的角色,請對比黑體字的部分。

                            

    public class LogDAOProxy implements MethodInterceptor
      {
           
    private Logger log=Logger.getLogger(LogDAOProxy.class);
           
    private Object dao=null;
           
    private Enhancer enhancer=new Enhancer();
            
    //返回DAO的子類
           public Object getDAO(Class clz,Object dao)
           {
               
    this.dao = dao;
               enhancer.setSuperclass(clz);
               enhancer.setCallback(
    this);
               
    return enhancer.create();
           }      
           
    //默認的攔截方法
          public Object intercept(Object o,Method method,Object[] args,

    MethodProxy proxy) throws Throwable
          {
               log.info(
    "調用日志方法"+method.getName());
               Object result
    =proxy.invoke(dao, args);
               
    return result;
          }
    }


    可見,原來模式里在getDao()時由enhancer創建dao,而 調用intercept時則將enhancer創建的dao以Object o參數傳回。
    而新模式里,dao在getDao()時從外面傳入,enhancer.create()返回的是一個proxy. 而調用intercept時,實際會用之前傳入的dao進行操作,而忽略Object o參數傳入的proxy。

    有點遺憾, intercept函數里MethodProxy的Signature是固定的,即客戶如果調用foo(String),你不可以用proxy.invoke偷換成foo(String,String);

    posted on 2008-10-08 10:38 Loy Fu 閱讀(404) 評論(0)  編輯  收藏 所屬分類: java
    主站蜘蛛池模板: 亚洲一区二区三区在线 | 国产精品久久免费| 亚洲日韩激情无码一区| 一级黄色毛片免费看| 亚洲AⅤ无码一区二区三区在线| 亚洲熟妇AV一区二区三区宅男| AV片在线观看免费| 最新亚洲精品国偷自产在线| 成年人免费观看视频网站| 亚洲中文字幕无码mv| 日韩成人在线免费视频| 亚洲av无码专区在线观看亚| 国产一级淫片视频免费看| 羞羞漫画小舞被黄漫免费| 国产91精品一区二区麻豆亚洲| 亚洲AV无码一区二区三区系列| 成人黄网站片免费视频| 亚洲视频免费在线看| 无码少妇一区二区浪潮免费| 亚洲色欲色欱wwW在线| 免费a级毛片无码a∨性按摩| 国产无遮挡色视频免费观看性色| 亚洲色欲久久久综合网东京热| 99热这里有免费国产精品| 亚洲午夜无码久久| 免费a级黄色毛片| 久久国产福利免费| 亚洲欧洲国产视频| 免费无码又爽又刺激网站| 亚洲男人的天堂在线播放| 免费精品人在线二线三线区别| 亚洲av综合日韩| 国产AV无码专区亚洲AV毛网站| h视频在线观看免费完整版| 国产亚洲精品va在线| 久热中文字幕在线精品免费| 爱爱帝国亚洲一区二区三区| 亚洲狠狠婷婷综合久久久久 | 国产偷伦视频免费观看| 自拍日韩亚洲一区在线| 亚洲人成色7777在线观看不卡|