Duffblog

          前進(jìn)一步,看看,需要前進(jìn)更大一步才可以。

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            5 隨筆 :: 53 文章 :: 5 評論 :: 0 Trackbacks
          反射、Proxy和元數(shù)據(jù)是Java最強(qiáng)的三個特征,再加上CGLib (Code Generation Library)和ASM,使得Java雖然沒有Ruby,Python般后生可畏,一樣能做出強(qiáng)悍的框架。
          ???Proxy可以看作是微型的AOP,明白提供了在繼承和委托之外的第三個代碼封裝途徑,只要有足夠的想象力,可以做得非常好玩,Spring的源碼里用Proxy就用得很隨便,看得我非常眼紅。可惜Proxy必須基于接口。因此Spring的做法,基于接口的用proxy,否則就用cglib。AOP么,一般小事非compoent一級的就不麻煩AspectJ出手了。

          ????cglib的Enhancer說起來神奇,用起來一頁紙不到就講完了。
          ??? 它的原理就是用Enhancer生成一個原有類的子類,并且設(shè)置好callback?, 則原有類的每個方法調(diào)用都會轉(zhuǎn)成調(diào)用實現(xiàn)了MethodInterceptor接口的proxy的intercept()?函數(shù):
          public?Object?intercept(Object?o,Method?method,Object[]?args,MethodProxy?proxy)

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

          ??? AOP沒有出現(xiàn)以前,該領(lǐng)域經(jīng)典的設(shè)計模式是Decorator,像Java IO Stream的設(shè)計就是如此.不過,如果為每個DAO, 每個方法的寫Decorator函數(shù)會寫死人的,所以用上cglib的好處是一次過攔截所有方法。?

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

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


          ???
          public?class?LogDAOProxy?implements?MethodInterceptor
          ???{
          ???????
          private?Logger?log=Logger.getLogger(AOPInstrumenter.class);
          ???????
          private?Enhancer?enhancer=new?Enhancer();
          ????????
          //返回DAO的子類
          ???????public?Object?getDAO(Class?clz)
          ???????{
          ???????????enhancer.setSuperclass(clz);
          ???????????enhancer.setCallback(
          this);
          ???????????
          return?enhancer.create();
          ???????}
          ???????
          //默認(rèn)的攔截方法
          ??????public?Object?intercept(Object?o,Method?method,Object[]?args,MethodProxy?proxy)?throws?Throwable
          ??????{
          ???????????log.info(
          "調(diào)用日志方法"+method.getName());
          ???????????Object?result
          =proxy.invokeSuper(o,args);
          ???????????
          return?result;
          ??????}
          ???}

          ??? 應(yīng)用的代碼:
          ????LogDAOProxy?proxy?=?new?LogDAOProxy();
          ????GoodsDAO??dao?
          =?(GoodsDAO)proxy.getDAO(GoodsDAO.class);
          ????dao.insert(goods);

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


          ??public?class?LogDAOProxy?implements?MethodInterceptor
          ??{
          ???????
          private?Logger?log=Logger.getLogger(AOPInstrumenter.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();
          ???????}??????
          ???????
          //默認(rèn)的攔截方法
          ??????public?Object?intercept(Object?o,Method?method,Object[]?args,MethodProxy?proxy)?throws?Throwable
          ??????{
          ???????????log.info(
          "調(diào)用日志方法"+method.getName());
          ???????????Object?result
          =proxy.invoke(dao,?args);
          ???????????
          return?result;
          ??????}
          ??}

          有點遺憾, intercept函數(shù)里MethodProxy的Signature是固定的 , 即客戶如果調(diào)用foo(String),你不可以用proxy.invoke偷換成foo(String,String);
          posted on 2006-06-17 20:30 追球者 閱讀(162) 評論(0)  編輯  收藏 所屬分類: 技術(shù)文摘
          主站蜘蛛池模板: 阳新县| 昌平区| 鄂托克旗| 长治市| 清新县| 廊坊市| 桦川县| 祁阳县| 堆龙德庆县| 凤山县| 乌兰县| 芦溪县| 贡嘎县| 攀枝花市| 石家庄市| 都兰县| 正安县| 江陵县| 漠河县| 宣威市| 屯昌县| 太仆寺旗| 麦盖提县| 绿春县| 嘉兴市| 隆德县| 镇江市| 安顺市| 虹口区| 贵南县| 恩平市| 襄垣县| 上高县| 彭州市| 新竹市| 江华| 沧州市| 交口县| 鄂伦春自治旗| 鄢陵县| 宜丰县|