CDI Features

概述

若是說EJB,JPA是以前JEE(JEE5及JEE5以前)中里程碑式的規範,那麼在JEE6,JEE7中CDI能夠與之媲美,CDI(Contexts and Dependency Injection),即上下文依賴注入,它是衆多JEE規範中的一個,從JEE6開始CDI正式成爲JEE規範,但CDI相關的概念不是新的,依賴注入的概念已經存在了許多年,相關的流行框架包括Spring,Google Guice等。目前CDI規範的實現主要有 JBoss Weld,Apache OpenWebBeans 和 Caucho CanDI,咱們隨後系列都是基於JBoss Weld進行。java

由Java Community Process介紹的Java Specification Request 299(JSR 299)的最終規範在2009年12月造成,JSR 299正式定義CDI爲JEE規範。在同一個月JSR 299在JSR316中被定義爲JEE6平臺的一部分。這意味着,每一個被認證爲JEE6兼容的應用程序服務器必須默認支持上下文和依賴注入。 爲了完整起見,咱們應該指出,CDI相關的依賴注入是在Java SE 規範JSR 330的基礎上進行的。以下爲CDI相關的JSR連接:web

JSR-299 - CDI: http://jcp.org/en/jsr/summary?id=299
JSR-316 - JEE 6: http://jcp.org/en/jsr/summary?id=316
JSR-330 - DI: http://jcp.org/en/jsr/summary?id=330安全

上下文

要徹底瞭解什麼是上下文,咱們首先須要明白web應用是怎樣運行的。現代計算機應用是可對話性質的,用戶發送請求開始啓動應用,傳入一些預約的數據單元,直到最後一個預先定義的工做完成,請求會接收到反饋輸出。這一過程當中在計算機和終端用戶之間存在着一些來回往復,計算機應用程序與用戶必須進行屢次交互,積累和處理數據直到它能夠構造出所指望的輸出。應用程序必須維護當前用戶的數據狀態,直到應用程序終止,這種類型的應用被認爲是「有狀態的」。Web應用程序使基於HTTP寫的,HTTP其自己是無狀態的,它是一種請求/響應協議,其中事務的狀態只有在一個請求的處理過程當中是活躍的。JEE服務器經過提供數據結構保存有狀態的數據來確保應用的「有狀態性」。當web應用程序使用Servlet規範,應用程序生命週期是可實現的,在生命週期的不一樣部分,有一些明肯定義的數據的範圍,咱們稱之爲上下文,具體包括:服務器

Application - 應用程序上下文,即數據在應用程序上下文中可用。換句話,數據在應用程序部署到應用程序卸載或刪除這段時間可用。這是最高級別的上下文。
Session - 會話上下文,即數據存儲在會話中,數據只有在會話被某一用戶建立到會話被移除這段時間內被這個用戶可用。
Request - 請求上下文,數據只有在同一個用戶的同一個請求中可用,當請求返回,數據再也不被服務器維護。
Conversation - CDI新增長的上下文,它的做用範圍是同一個會話上下文的幾個請求的總和。以下圖所示爲Conversation示意圖:數據結構

依賴注入

依賴注入,便是由CDI定義的依賴注入,is the process by which objects can be inserted into ther application objects in a typesafe manner. The decision of which particular implementation of an object will be injected can be delayed until the time of application deployment. In other frameworks injection is based upon string matching. CDI improves upon this through typed injection where the types are checked at compile time. This exposes injection errors earlier in the development lifecycle and makes debugging easier.app

依賴注入的一個最大的好處是應用組件之間的鬆耦合。The client and server components are loosely coupled because several different versions of the server can be injected into the client. The client works with an interface and is oblivious to which server it is talking to. Taking advantage of the deploy time injection, we can use specific objects for different types of environments such as production and test environments. For example, we can inject a production or test datasource depending upon our deployment environment.框架

其餘CDI的特性

除了上下文和依賴注入外,CDI還提供了一些其餘特性:ui

EL表達式的擴展:CDI中默認支持EL表達式並對其進行了擴展,好比在JSF或JSP中,默認是不支持EL表達式傳參的,若是結合CDI,那麼就能夠在EL表達式中傳參數給後臺Bean。
攔截器:CDI提供了一個十分方便的方法來實現一個或多個攔截器,用來處理 cross-cutting concerns such as logging
裝飾器:裝飾器可讓你動態的擴展或者重寫現有的業務接口。這個功能十分方便,在CDI中,你在調用一個接口的實現類的時候,無須關心這個實現類的名稱,因此在你更換新的實現的時候無需去修改你的代碼,只須要在新的接口上面經過裝飾器聲明你要替換的以前的接口實現,而後在 bean.xml 中聲明一下便可。
事件:CDI 提供了一種鬆耦合性的事件發送和接受機制。好比,在用戶登錄後,咱們須要在Session中存放一些用戶信息。有了這個機制,咱們不須要在登錄的那個方法中 經過new一個Session範圍的對象或者把一些數據放入Session中,這樣修改這些方法的時候,咱們就得去修改這個登錄方法的。或者說 咱們忽然須要在用戶登錄後,額外作一些事情,咱們又得去修改登錄這塊的代碼。 在CDI中,咱們能夠在登錄成功後,發送出一個登錄成功的事件,而後咱們能夠在任何類中來接受這個事件,來完成對應的工做。
類型安全:CDI不在經過字符串名稱來注入對象,而經過java類型來肯定被注入的對象。當只是經過java類型還不能肯定到底哪個對象被注入的時候,你能夠經過擴展 @Qualifier 註解來限定你須要注入的對象。
註解:CDI中全部的注入都是經過註解來完成的,XML相關的配置很是少
普通的Java Bean :在CDI中基本上全部的 Java Bean 均可以被注入。固然包括:EJB、JNDI資源、持久化單元、持久化上下文、接口等等。this

相關文章
相關標籤/搜索