博客 / 詳情

返回

CDI演示

CDI演示

通過CDI的類型安全的事件通知特性來可使組件之間解耦

該示例演示了事件的發佈和觀察:

CDI演示代碼

源碼: https://github.com/ximinghui/cdi-study.git










後續拓展內容

知識點1:Bean的獲取

// 當只存在一個Bean時,可以直接通過CDI規範定義的CDI接口直接獲取到這個Bean對象
MyBean myBean = CDI.current().select(MyBean.class).get();
// 如果存在多個Bean,則應該通過標識符明確指定想要注入的Bean

知識點2:Spring 和 DI、CDI 三者之間的關係

這裏的 Spring 也就是我們常説的Spring依賴注入,指的是 Spring Context 和 Spring Beans 所提供的依賴注入能力。它倆誕生於2004年,DI並不是它們的全部功能。

這裏的 DI 指的是Java官方的“依賴注入”規範,即JSR 330,該JSR於2009年提出並最終成為Java標準的一部分,Maven座標為javax.inject。Oracle公司2017年9月決定 將Java EE交給Eclipse基金會 管理,因此它現在名叫 Jakarta Dependency Injection ,並搬了新家,當前官網為 https://jakarta.ee/specifications/dependency-injection/,Maven座標為 jakarta.inject-api。

這裏的 CDI 是Java官方的“上下文和依賴注入”規範,指 JSR 299。該JSR早在2006年就提出了,但是2009年才最終通過併成為Java標準的的一部分,同年提出並通過了上面的JSR 330。最初為 CDI APIs,同樣在Eclipse接管後改名為 Jakarta Contexts and Dependency Injection,當前官網https://jakarta.ee/specifications/cdi/,Maven座標 jakarta.enterprise.cdi-api。

DI 很簡單,從實際應用到代碼的角度來看,它只定義了6個註解,只是一種標記、一種聲明,除此之外什麼都沒有:

DI的項目結構

CDI 定義了一組行為,賦予DI中6個註解意義,比如如果一個方法的入參前有@Inject註解,應注入一個對象到這裏,等等。CDI也是規範,只定義了期望的東西,但不具體去做這些。具體去做這些的叫CDI的Provider或CDI的實現,比如Weld、OpenWebBeans等(注意,Spring依賴注入並不是CDI實現)。所以這裏也體現了CDI的特性,標準化:凡是上下文和依賴注入相關的,我只需要在Java裏這麼用就完了,不會有不同庫/框架註解不同的情況。靈活性、可替換性:我的代碼是面向CDI的,我只依賴了CDI的jar包。具體讓哪個庫幫我做依賴注入這些事情,我只需要把它放到classpath中就行了。今天用Weld,明天改OpenWebBeans只需要pom.xml換個依賴項就行。

Spring依賴注入 就是最熟悉、用的最多的了。它是一套自己的體系,有自己的註解(相當於JSR 330),有自己的註解行為解釋(相當於JSR 299,即什麼註解應該幹什麼事情),和自己去親自幹這些依賴注入的事情(相當於CDI的實現)。因此,對於目前的Spring Boot項目,如果沒有想用CDI想法或對依賴注入沒有什麼特別要求,什麼依賴(指DI和CDI或者實現)都不需要引入,直接就能@Autowried、@Qualifier這樣使用。
Spring不支持JSR 299但是支持JSR330,也就是用@Inject替代@Autowired一樣正常工作。如果在意代碼可移植性的情況,也可考慮使用Spring依賴注入但是代碼中用JSR 330的註解。

user avatar lankerens 頭像 codingdgsun 頭像 mokeywie 頭像 nian_5aedc008c1353 頭像
4 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.