java - 如何注入(inject)同一类不同作用域的对象?

标签 java java-ee-6 cdi jboss-weld jsr299

就简单性和正确性而言,注入(inject)具有不同作用域的同一类的对象的最佳方法是什么?

在 servlet 中,我想注入(inject)具有不同作用域的同一类的对象。 还是不知道要不要用jsf。

  • 简单:为每个范围创建一个Qualifier和一个生产者方法太多了;制作一个接口(interface)、两个类并在 beans.xml 中添加和替代也太多了;拥有 Address#isCurrent() 方法没有意义。
  • 正确性:JSR299, 3.11 说:不建议使用 @Named 作为注入(inject)点限定符。仍然不知道为什么。
    尽管在注入(inject)点使用 @Named 可以与 @ApplicationScoped 一起使用,并且 @RequestScoped 但不适用于 @SessionScoped。请参阅下面的命名片段

在 Spring 这很容易:
Spring 片段

<bean id="currentAddress" class="xxx.Address" scope="session" />
<bean id="newAddress" class="xxx.Address" scope="request" />
<bean id="servlet" class="xxx.MyServlet">
 <property name="currentAddress" ref="currentAddress" />
 <property name="newAddress" ref="newAddress" />
</bean>


命名片段

/* Address class */
@Produces @RequestScoped @Named(value="request")
 public Address getNewAddress(){
 return new Address();
}

@Produces @SessionScoped @Named(value="application")
 public Address getCurrentAddress(){
 return new Address();
}
/* Servlet */
@Inject @RequestScoped @Named("request")  private Address newAddress;
@Inject @ApplicationScoped @Named("application") private Address currentAddress;

最佳答案

包含此建议的原因与人们更喜欢枚举而不是任意字符串常量的原因相同,那就是因为它不是类型安全的。您很容易输错类的名称,它可以正常编译,但在运行时会失败。之所以包含此建议,是因为在大多数情况下,当您有能力在编译时强制这些约束时,@named 会使您的应用程序变得不必要的脆弱。

这是一个good article概述了原因:

处理这种情况的首选方法是使用带有枚举值的@Qualifiers。查看标题为“字符串限定符是旧版”和“正确方法”的部分,了解处理此问题的步骤。

关于java - 如何注入(inject)同一类不同作用域的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10373617/

相关文章:

java - 如何在后台运行程序

java - Java EE 中的数据库操作

java - JEE : how to pass parameter to an interceptor

jsf - Weld -001408 : Unsatisfied dependencies for type Employee with qualifiers @Default

java - WeldContainer 和 SeContainer

maven - 如何使用 CDI 和 JAX-RS、Java EE7 配置 Tomcat 9?

java - 如何在输入表单中包含 '?

java - 如何实现多线程以调用多个数据的 REST URL

java - Ant build.xml 不读取环境属性

java - NetBeans:在 Web 模块的 EJB 模块中使用 EJB