欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
Java下的框架編程(反射,泛型,元數據,CGLib,代碼動(dòng)態(tài)生成,AOP,動(dòng)態(tài)語(yǔ)言嵌入)
作者:江南白衣
                                                
   以Ruby為助力的Ruby on Rails 橫空出世,又刷新了一次人們對Framework的認識:Closures、Maxin、Continuations、Metaprogramming、Reflection,又一堆名詞砸得人悴不及防。
      Java 雖然沒(méi)有動(dòng)態(tài)語(yǔ)言般暴起,但仍然天連天,水接水的生出好多框架技術(shù)---反射(reflection),泛型(generics),元數據(annotation),proxies(proxy/cglib),代碼動(dòng)態(tài)生成(asm),AOP(aspectJ),動(dòng)態(tài)語(yǔ)言嵌入(groovy/javascript/beanshell)。面對著(zhù)這些,我們像一夜暴富的農企,有點(diǎn)手足無(wú)措的樣子。

    第一感覺(jué),應該出現新的Design Pattern書(shū)籍了。
    多年前基于純C++語(yǔ)法寫(xiě)就的那本經(jīng)典,很多模式都可以被更優(yōu)雅的實(shí)現,還有更多的新模式,會(huì )隨著(zhù)這些技術(shù)的推廣而出現。

    第二感覺(jué),新的框架模式出現了。
    不斷升級自己的Spring,綜合運用了除泛型外的大部分技術(shù),把編程界的想像力MFC/ EJB2.0 Container這樣傳統的template模式/鉤子函數的思路,向完全無(wú)侵入的標準過(guò)渡。
    當你不顧性能狂用反射時(shí),C++下的遺憾感開(kāi)始越來(lái)越遠。
    
    第三感覺(jué),自己應該重新充電了。
    從C++下編寫(xiě)框架的經(jīng)歷到盡用“反射,泛型,元數據,proxy,代碼動(dòng)態(tài)生成,AOP,動(dòng)態(tài)語(yǔ)言嵌入”是一條明顯的分界線(xiàn),自己應該調度足夠的業(yè)余時(shí)間,沉實(shí)的學(xué)習一遍。

    這個(gè)系列開(kāi)始一個(gè)個(gè)介紹上述的積木。

Java5泛型的用法,T.class的獲取和為擦拭法站臺

作者:江南白衣 

   Java 5的泛型語(yǔ)法已經(jīng)有太多書(shū)講了,這里不再打字貼書(shū)。GP一定有用,不然Java和C#不會(huì )約好了似的同時(shí)開(kāi)始支持GP。但大家也清楚,GP和Ruby式的動(dòng)態(tài)OO語(yǔ)言屬于不同的意識形態(tài),如果是一人一票,我想大部分的平民程序員更熱衷動(dòng)態(tài)OO語(yǔ)言的平白自然。但如果不準備跳槽到支持JSR223的動(dòng)態(tài)語(yǔ)言,那還是看看GP吧。

   胡亂總結泛型的四點(diǎn)作用:
   第一是泛化,可以拿個(gè)T代表任意類(lèi)型。 但GP是被C++嚴苛的靜態(tài)性逼出來(lái)的,落到Java、C#這樣的花語(yǔ)平原里----所有對象除幾個(gè)原始類(lèi)型外都派生于Object,再加上Java的反射功能,Java的Collection庫沒(méi)有范型一樣過(guò)得好好的。

   第二是泛型 + 反射,原本因為Java的泛型拿不到T.class而覺(jué)得泛型沒(méi)用,最近才剛剛學(xué)到通過(guò)反射的API來(lái)獲取T的Class,后述。

   第三是收斂,就是增加了類(lèi)型安全,減少了強制類(lèi)型轉換的代碼。這點(diǎn)倒是Java Collection歷來(lái)的弱項。

   第四是可以在編譯期搞很多東西,比如MetaProgramming。但除非能完全封閉于框架內部,框架的使用者和擴展者都不用學(xué)習這些東西的用法,否則那就是自絕于人民的票房毒藥。C++的MetaProgramming好厲害吧,但對比一下Python拿Meta Programming生造一個(gè)Class出來(lái)的簡(jiǎn)便語(yǔ)法,就明白什么才是真正的叫好又叫座。

   所以,作為一個(gè)架構設計師,應該使用上述的第2,3項用法,在框架類(lèi)里配合使用反射和泛型,使得框架的能力更強; 同時(shí)采用收斂特性,本著(zhù)對人民負責的精神,用泛型使框架更加類(lèi)型安全,更少強制類(lèi)型轉換。
   
   擦拭法避免了Java的流血分裂 :
    大家經(jīng)常罵Java GP的擦拭法實(shí)現,但我覺(jué)得多虧于它的中庸特性---如果你用就是范型,不用就是普通Object,避免了Java陣營(yíng)又要經(jīng)歷一場(chǎng)to be or not to be的分裂。 
    最大的例子莫過(guò)Java 5的Collection 框架, 比如有些同學(xué)堅持認為自己不會(huì )白癡到類(lèi)型出錯,而且難以忍受每個(gè)定義的地方都要帶一個(gè)泛型定義List〈Book〉,不用強制類(lèi)型轉換所省下的代碼還不夠N處定義花的(對了,java里面還沒(méi)有tyepdef.....),因此對范型十分不感冒,這時(shí)就要齊齊感謝這個(gè)搽拭法讓你依然可以對一個(gè)泛型框架保持非泛型的用法了...

   通過(guò)反射獲得 T.class:
   
    不知為何書(shū)上不怎么講這個(gè),是差沙告訴我才知道的,最經(jīng)典的應用見(jiàn)Hibernate wiki的Generic Data Access Objects, 代碼如下: 
abstract public class BaseHibernateEntityDao<T> extends HibernateDaoSupport {
 
private Class<T> entityClass;
 
public BaseHibernateEntityDao() {
        entityClass 
=(Class<T>) ((ParameterizedType) getClass()
                                .getGenericSuperclass()).getActualTypeArguments()[0];
    }
 
public T get(Serializable id) {
        T o 
= (T) getHibernateTemplate().get(entityClass, id);
}
}

  精華就是這句了:
Class<T> entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; 

  泛型之后,所有BaseHibernateEntityDao的子類(lèi)只要定義了泛型,就無(wú)需再重載getEnttityClass(),get()函數和find()函數,銷(xiāo)益挺明顯的,所以SpringSide的Dao基類(lèi)毫不猶豫就泛型了。

  不過(guò)擦拭法的大棒仍在,所以子類(lèi)的泛型語(yǔ)法可不能亂寫(xiě),最正確的用法只有:
   
public class BookDao extends BaseHibernateEntityDao<Book>
 

Java下的框架編程(3)--關(guān)于反射的碎話(huà)

     反射,所有教科書(shū)都正兒八經(jīng)的講了,這里只能再隨便講兩句。

     反射是一種讓框架能夠根據 "以字符串形式存在的信息" 來(lái)調用對象的屬性和函數的技術(shù),是Java對C++最大的進(jìn)步之一---讓框架編程真正走向平民化。MFC年代,無(wú)論侯捷如何深入淺出,還在念大學(xué)的我就是搞不懂那些注冊"消息--函數映射"的魔法宏。

     不過(guò)Java的反射也就是對著(zhù)C++比較自豪而以,因為C#,Ruby,Python甚至php都標配了反射的功能。而且,人家的反射語(yǔ)法都是內嵌在基礎Object類(lèi)的,拿最弱的php來(lái)看:
$func_name="helloworld";
$foo->$func_name;

     而Java,卻搞出了Class,Methed, Field,Constructor這么一大堆類(lèi)出來(lái)。本來(lái)這是Java設計師很?chē)乐?,很cool的體現,問(wèn)題是它居然不提供一種集成的簡(jiǎn)便的寫(xiě)法......相同的情形還出現在Java的I/O 類(lèi)庫里。
    微軟這方面就做得好些,懂得討好開(kāi)發(fā)人員。

    因為Java的無(wú)情,就搞得大家的項目里要自制BeanUtils了。幸虧Apache Jakarta Commons 已經(jīng)做了一個(gè)比較好的,可以直接使用--以前寫(xiě)的介紹文章。
    另外Spring也做了一個(gè)。

    閑得沒(méi)事做的,還可以emule一本〈Relection in action〉回來(lái)看。

    而C++下面的"反射",見(jiàn)我偶像di文章。另還有一個(gè)比較BT的C++框架叫ACDK的,把自己整得和Java很像,有反射和垃圾收集,甚至和JSDK差不多的線(xiàn)程,Unicode,I/O,網(wǎng)絡(luò ),XML API??上У氖?,即使到了C++0x, B大叔還是不準備在語(yǔ)言級支持反射。
 

Java下的框架編程(4)--Annotation vs XML vs Interface 最新一Round

作者:江南白衣 

1.因為兩者的用途不同,所以Annotation與XML應該并存

 Anootation vs XML 到了現在,在Spring和EJB3各占一邊的持續演示下,各自的用途已清晰。
   雖然兩者之間完全可以相互替代,沒(méi)有絕對不能做的事情,但卻存在好不好的問(wèn)題,兩者的用途不同,應該并用:

   "size=10,db_user=ito"這樣的參數,仍然適合放在XML,YAML(ruby),properties,ini文件里。
    而Annotation中所放,是真正程序的一部分,是舊編程體系中所缺的那一塊東西。
 看看編程語(yǔ)言的發(fā)展:
    一開(kāi)始只是函數的封裝;
    到了OO語(yǔ)言,對象有了自己的屬性和方法;
    到了框架滿(mǎn)天飛的年代,這些屬性和方法又有了自己的屬性,來(lái)告訴框架如何為自己提供服務(wù)。比如Spring和EJB3,POJO就用配置信息來(lái)告訴框架無(wú)侵入的提供服務(wù)。整個(gè)進(jìn)化的過(guò)程非常自然。

    因為這些信息本來(lái)就是程序的一部分,所以應該仍然放在Code里頭,Spring把它割裂到XML明顯影響了代碼的閱讀。

2.Anotation/XML PK Interface,Spring 無(wú)侵入性的基礎
   切爾斯基的Blog講了Annotation/XML 對Interface的PK。這次PK,也可以認為是Spring 對 EJB2.1在框架無(wú)侵入性上的一次PK。
   在EJB2.1時(shí)代,POJO必須通過(guò)接口來(lái)向框架聲明一些東西,這就造成了框架的侵入性,強迫POJO實(shí)現一堆接口。而Spring,把這些元信息搬到了XML配置文件。
 在Spring里隨便就可以舉個(gè)例子。比如一個(gè)POJO,在Spring為它進(jìn)行依賴(lài)注入A和B后,需要根據A和B來(lái)裝配一個(gè)內部屬性C,這樣就需要再跑一個(gè)init()函數。Spring提供兩種方式,一種侵入性的,實(shí)現InitializingBean接口的afterPropertiesSet()函數供Spring調用。   而另一種是無(wú)侵入性的,在Bean的xml節點(diǎn)里面自行定義init函數的名字。

3.Annotation目前的弱點(diǎn)
 一是Hibernate、Struts、三姑媽、四姨婆的annotation如果一股腦兒的全堆在可憐的POJO上很沒(méi)人道,如果三姑六婆都搶Transation這個(gè)Anontation就更慘了。
    二是annoation的表達能力有限,不如XML的強。

4.JSR250 - Common Annotations for the Java
    Final Draft已經(jīng)發(fā)布,八卦回來(lái)一看,也只是多定義了幾個(gè)Common Annotation而已。
   1.Generated  自動(dòng)生成的代碼要用此聲明,而且必須說(shuō)明工具的名稱(chēng),如@Generated(“com.sun.xml.rpc.AProcessor”)

   2.Resource/Resources 就是EJB3里面用的資源引用。

   3.PostConstruct / PreDestroy 聲明那些如題的函數。
  
   還有一些安全方面的annotation,不關(guān)心
 

Java下的框架編程(5)--cglib的應用

   作者:江南白衣 

   反射、Proxy和元數據是Java最強的三個(gè)特征,再加上CGLib (Code Generation Library)和ASM,使得Java雖然沒(méi)有Ruby,Python般后生可畏,一樣能做出強悍的框架。
   Proxy可以看作是微型的AOP,明白提供了在繼承和委托之外的第三個(gè)代碼封裝途徑,只要有足夠的想象力,可以做得非常好玩,Spring的源碼里用Proxy就用得很隨便,看得我非常眼紅??上roxy必須基于接口。因此Spring的做法,基于接口的用proxy,否則就用cglib。AOP么,一般小事非compoent一級的就不麻煩AspectJ出手了。

    cglib的Enhancer說(shuō)起來(lái)神奇,用起來(lái)一頁(yè)紙不到就講完了。
    它的原理就是用Enhancer生成一個(gè)原有類(lèi)的子類(lèi),并且設置好callback到proxy, 則原有類(lèi)的每個(gè)方法調用都會(huì )轉為調用實(shí)現了MethodInterceptor接口的proxy的intercept() 函數:
public Object intercept(Object o,Method method,Object[] args,MethodProxy proxy)

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

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

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

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


   
public class LogDAOProxy implements MethodInterceptor
   {
       
private Logger log=Logger.getLogger(LogDAOProxy.class);
       
private Enhancer enhancer=new Enhancer();
        
//返回DAO的子類(lèi)
       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();創(chuàng )建子類(lèi)實(shí)例,但在Spring管理下,一些Bean的實(shí)例必須由Spring來(lái)創(chuàng )建和管理,而不由enhancer來(lái)創(chuàng )建的。所以我對上述用法略加修改,使它真正當一個(gè)Proxy的角色,請對比黑體字的部分


  public class LogDAOProxy implements MethodInterceptor
  {
       
private Logger log=Logger.getLogger(LogDAOProxy.class);
       
private Object dao=null;
       
private Enhancer enhancer=new Enhancer();
        
//返回DAO的子類(lèi)
       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;
      }
  }

可見(jiàn),原來(lái)模式里在getDao()時(shí)由enhancer創(chuàng )建dao,而 調用intercept時(shí)則將enhancer創(chuàng )建的dao以Object o參數傳回。
而新模式里,dao在getDao()時(shí)從外面傳入,enhancer.create()返回的是一個(gè)proxy. 而調用intercept時(shí),實(shí)際會(huì )用之前傳入的dao進(jìn)行操作,而忽略Object o參數傳入的proxy.

有點(diǎn)遺憾, intercept函數里MethodProxy的Signature是固定的 , 即客戶(hù)如果調用foo(String),你不可以用proxy.invoke偷換成foo(String,String);
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
實(shí)戰CGLib系列之proxy篇(一):方法攔截MethodInterceptor
CGLIB是什么
jdk動(dòng)態(tài)代理和cglib代理總結
Java-06:動(dòng)態(tài)代理
java動(dòng)態(tài)代理(JDK和cglib)
一個(gè)小例子演示 cglib 動(dòng)態(tài)代理庫
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久