1.概述
上下文和依赖注入(CDI)是Java EE的一项功能,可帮助融合Java EE 6和更高版本中包含的平台的Web层和事务层。 从技术角度来看,这意味着CDI提供了依赖项注入框架,并且还管理了依赖项的生命周期。
今天在本教程中,我们将介绍Java EE 7的CDI。
1.1上下文和依赖注入规范
如Oracle的Java EE 7网站上所述 ,Java EE 7使用CDI 1.1,在JSR 346中对此进行了概述。
正如CDI负责人Pete Muir在本博客中提到的, CDI 1.1带来了许多重大更改,例如:
- 全局启用拦截器,全局启用装饰器,以及使用@Priority批注的替代方法
- 对构造函数的@AroundConstruct生命周期回调的支持
- EventMetadata允许检查事件元数据
- 允许将拦截器绑定到构造函数
如前所述,博客文章中还提到了其他重大更改,建议将它们全部复习。
2.比较依赖注入和资源注入
射出类型 | 可以直接注入JNDI资源 | 可以直接注入常规课程 | 解决依据 | 类型安全 |
资源注入 | 真正 | 假 | 资源名称 | 没有 |
依赖注入 | 假 | 真正 | 类型 | 是 |
2.1依赖注入
依赖注入使我们能够将常规Java类转换为托管对象,并将这些托管对象注入其他托管对象。 障碍是确保我们在正确的时间提供正确的管理对象。
在这里,我们有一个@Inject批注,它表示我们将提供(也称为注入)此构造函数的依赖项:
@Injectpublic MaskingDataProcessor(MaskingData maskingData) {this.maskingData = maskingData;}
那么,这种依赖关系从何而来?
在此示例中,我们有两个类: SSNDataMasker和BirthdayMasker ,它们都实现相同的接口。
SSNDataMasker注释为默认值,因此,如果可用,将默认选择:
@Default
public class SSNMasker implements MaskingData {...
}
BirthdayMasker被注释为替代依赖项,因此,如果SSNDataMasker不可用,则会选择它:
@Alternative
public class BirthdayMasker implements MaskingData {...
}
2.2资源注入
资源注入使我们能够将JNDI名称空间中可用的任何资源注入到容器管理的任何对象中。 例如,我们可以使用资源注入来注入连接器,数据源或JNDI名称空间中可用的任何其他资源。
在下面的代码中,我们将数据源对象注入到字段中,这种资源注入被适当地称为基于字段的注入:
public class MyClass {@Resource(name="java:comp/SomeDataSource")private DataSource myDataBase;...
}
注入资源的另一种方法是基于方法的注入 。 在基于方法的注入中,所传递的参数与资源一起注入:
public class MyClass {private DataSource myDataBase;...@Resource(name="java:comp/SomeDataSource")public void setMyDataSource(DataSource dataSource) {myDataBase = dataSource;}
}
3. EJB和CDI有什么区别?
正如Oracle网站上的这篇文章所述 ,CDI中的“ C”是EJB bean和CDI bean之间的主要区别。 EJB组件可能是有状态的,但并不是固有的上下文关系。 当我们引用有状态组件实例时,必须在客户端之间显式传递该实例,并由应用程序销毁它。 CDI通过上下文生命周期管理改进了EJB组件模型 。 但是,有时候我们想彼此使用。
3.1何时使用EJB
只有通过添加@ Stateful,@ Stateless或@Singleton来使CDI bean成为EJB时,才有几种有用的容器服务可用。
示例包括:
- 当我们公开一个JAX-WS @WebService时 ,使其成为EJB使得我们不必列出它并将其映射为xml文件中的servlet。 @Stateless和@Singleton可以使用此功能。
- 当我们通过@Path公开JAX-RS资源时。 当RESTful服务是EJB时,我们将获得自动发现,不需要将其添加到JAX-RS Application子类或其他地方。 @Stateless和@Singleton可以使用此功能。
- 当我们并行工作时, @Asynchronous方法调用非常有用。 众所周知,线程过多会降低性能。 @Asynchronous批注允许我们并行化使用容器的线程池执行的操作。 @ Stateful,@ Stateless和@Singleton可以使用此功能。
3.2何时使用CDI
简而言之,当我们受益于CDI时,就应该使用CDI。 当我们需要注入,事件,拦截器,修饰器,生命周期跟踪以及CDI提供的其他功能时。
4。结论
为了快速测试我们回顾的有关CDI的概念,让我们将Weld添加到Maven项目中:
<dependency><groupId>org.jboss.weld.se</groupId><artifactId>weld-se-core</artifactId><version>2.4.1.Final</version>
</dependency>
假设我们已经有要测试的代码(例如博客文章中先前提到的代码),我们只需要执行Weld,例如:
public static void main(String[] args) {Weld weld = new Weld();WeldContainer container = weld.initialize();MaskingDataProcessor maskingDataProcessor = container.select(MaskingDataProcessor.class).get();container.shutdown();}
翻译自: https://www.javacodegeeks.com/2018/10/resource-dependency-injection-java-ee-7.html