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 ContextSpring 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的注解。


Xi_Minghui
1 声望0 粉丝

一枚普普通通的程序猿