如何注入了不同作用域的同一类的对象?(How to inject objects of the sa

2019-07-29 04:33发布

在简单性和正确性而言,什么是注射了不同作用域的同一类对象的最佳方式?

在一个servlet我想注入了相同的类的对象用不同的作用域。 不过不知道是否要使用JSF。

  • 简单性:制作一个Qualifier和每个范围生产者方法是太多; 形成交界面,两个阶级,添加和替代在beans.xml也太多; 具有Address#isCurrent()方法没有意义。
  • 正确性:JSR299,3.11说: 不建议作为注入点限定符使用@Named的。 不过不知道为什么。
    虽然使用@Named于注射点可与@ApplicationScoped@RequestScoped但与@SessionScoped 。 见下文命名片段

在春天,它是很容易的:
春天片段

<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;

Answer 1:

究其原因,包括这一建议的道理是一样的人会愿意在枚举常量任意的字符串,这是因为它不是类型安全的。 你可以很容易输错的类的名称,它将编译罚款,并在运行时失败。 该建议是因为在大多数情况下,@Named让你的应用程序不必要的脆弱,当你有能力的部队在编译时这些限制包括在内。

这里是一个很好的文章 ,列出的理由:

处理这种情况的首选方式是使用@Qualifiers与枚举值。 结帐题为“字符串限定符是传统”和“正确的方式”的步骤来处理这个部分。



Answer 2:

感谢@ nsfyn55用于指出好文章 ,阅读节“正确的方式”后,我想出了什么,我认为是要实现它的简单性和正确性方面的最佳途径。

所以我只用一个限定词注释界面。

/* Qualifier annotation */
@Qualifier
@Retention(RUNTIME)
@Target({FIELD,METHOD})
public @interface Scope {

 Type value();

 enum Type { REQUEST, SESSION, APPLICATION };
}


/* Address class */
@Produces @Scope(REQUEST) @RequestScoped
 public Address request() {
 return new Address();
}

@Produces @Scope(SESSION) @SessionScoped
 public Address session() {
 return new Address();
}

/* Servlet */
@Inject @Scope(REQUEST)
private Address newAddress;

@Inject @Scope(SESSION)
private Address currentAddress;


文章来源: How to inject objects of the same class with different scopes?