2013年1月29日 星期二

Java EE 6 CDI

自從去年還是前年去聽過Chuck,Lee 的CDI介紹之後,雖然有偶爾玩看看一些簡單的sample,可是還是沒有真的從頭到尾好好搞清楚什麼叫做CDI,以及它的使用範圍與限制,趁現在來補一下Oracle 推出的tutorial來看看。

在使用CDI的時候,對Bean這個字彙其實有了一個全新的定義,有別於其他的java technology,像是EJB, JavaBeans等等,在CDI的世界裡,Bean的定義是在整個應用程式中,具有上下文關係(Contextual)可控制存取的一個物件,這個物件包含了各種可儲存的資訊以及其邏輯方法操作,任何一個Java EE 物件都可以被稱之為Bean,只要這些物件的生命週期是在Container裏頭可以被掌握管理的,那麼我們就可稱之為CDI的Bean。

但也不是每一個任意物件都可以被稱之為Bean的,他起碼有幾點限制:

  • it is not a nonstatic inner class
  • it is a concrete class or is annotated with @Decorator
  • it is not annotated with an EJB component-defining annotation or declared as an EJB bean class in ejb-jar.xml
  • it has an appropriate constructor. one of the following is the case:
    • The class has a constructor with no args.
    • The class declares a constructor annotated @Inject
說完了Bean的定義之後,回頭看看,所謂的CDI 的Inject,注入這個觀念由來已久,在此先略過強大的SpringFramework,我只單看在JavaEE 6 當中,哪些類型的Bean是可以被注入的?
  • 幾乎可以是任意Java class
  • Session Beans
  • Java EE Resources , aka. Data Sources, JMS Topics / Queues, Connection Factories ... etc
  • Persistence Contexts (JPA EntityManager objects)
  • Producer fields( ?  這是在公啥毀? )
  • Objects returned by producer methods
  • Web Service References
  • Remote Enterprise bean references
CDI 在注入時也是有其範圍限制,可參考下圖

特別要注意的是當Scope為Session/Application/Conversation時,這些managed bean必須實作Serializable。

當我們完成了bean的設置之後,必須為他給個名字,使得EL 可以存取這個managed bean,這裡使用的annotation tag是 @Named , 範例如下圖


在這範例中,我將Greeting 的EL 存取名稱命名為 MyGreet,之後便可在Facelet當中來快速的取用他了



沒有留言: