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批注,它表示我们将提供(也称为注入)此构造函数的依赖项:

@Inject
	public 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