Java 如何使用不同的作用域注入同一类的对象?

Java 如何使用不同的作用域注入同一类的对象?,java,java-ee-6,cdi,jboss-weld,jsr299,Java,Java Ee 6,Cdi,Jboss Weld,Jsr299,就简单性和正确性而言,向同一类的对象注入不同作用域的最佳方法是什么? 在一个servlet中,我希望注入具有不同作用域的同一类的对象。 仍然不知道是否要使用jsf 简单性:为每个范围制作一个限定符和一个生产者方法太多了;在beans.xml中制作一个接口、两个类以及添加和替换也太多了;使用地址#isCurrent()方法没有意义 正确性:JSR299,3.11说:不建议使用@Named作为注入点限定符。还是不知道为什么。 尽管在注入点使用@Named可以与@ApplicationScoped和

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

在一个servlet中,我希望注入具有不同作用域的同一类的对象。 仍然不知道是否要使用jsf

  • 简单性:为每个范围制作一个
    限定符和一个生产者方法太多了;在
    beans.xml
    中制作一个接口、两个类以及添加和替换也太多了;使用
    地址#isCurrent()
    方法没有意义
  • 正确性:JSR299,3.11说:不建议使用@Named作为注入点限定符。还是不知道为什么。
    尽管在注入点使用
    @Named
    可以与
    @ApplicationScoped
    @RequestScoped
    ,但不使用
    @SessionScoped
    。请参阅下面的命名代码段
春天很容易:
Spring片段



命名片段

/*地址类*/
@生成@RequestScoped@Named(value=“request”)
公共广播getNewAddress(){
返回新地址();
}
@生成@SessionScoped@Named(value=“application”)
公共地址getCurrentAddress(){
返回新地址();
}
/*Servlet*/
@注入@RequestScoped@Named(“request”)私有地址newAddress;
@注入@ApplicationScoped@Named(“应用程序”)私有地址currentAddress;

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

以下是一份概述原因的报告:


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

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

以下是一份概述原因的报告:


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

感谢@nsfyn55指出,在阅读了“正确的方法”一节之后,我提出了我认为在简单性和正确性方面实现此目的的最佳方法

因此,我只为限定符注释使用一个接口

/*限定符注释*/
@限定词
@保留(运行时)
@目标({字段,方法})
公共@接口范围{
类型值();
枚举类型{请求、会话、应用程序};
}
/*地址类*/
@生成@Scope(REQUEST)@RequestScoped
公共广播请求(){
返回新地址();
}
@生成@Scope(SESSION)@SessionScoped
公开演讲会(){
返回新地址();
}
/*Servlet*/
@注入@Scope(请求)
私人地址新地址;
@注入@Scope(会话)
私人地址;

感谢@nsfyn55指出,在阅读了“正确的方法”一节之后,我想出了我认为在简单性和正确性方面实现它的最佳方法

因此,我只为限定符注释使用一个接口

/*限定符注释*/
@限定词
@保留(运行时)
@目标({字段,方法})
公共@接口范围{
类型值();
枚举类型{请求、会话、应用程序};
}
/*地址类*/
@生成@Scope(REQUEST)@RequestScoped
公共广播请求(){
返回新地址();
}
@生成@Scope(SESSION)@SessionScoped
公开演讲会(){
返回新地址();
}
/*Servlet*/
@注入@Scope(请求)
私人地址新地址;
@注入@Scope(会话)
私人地址;

非常感谢您的回答。我可以看出不鼓励使用@Named(“string”)的原因。读了这篇文章后,你建议我有一个新的想法,我更喜欢:两种方法只有一个限定符。稍后我会尝试。我编辑了@Qualifier annotation上我提到的帖子,作为处理此问题的首选方法。谢谢,我刚刚添加了我的答案,非常感谢你的回答。我可以看出不鼓励使用@Named(“string”)的原因。读了这篇文章后,你建议我有一个新的想法,我更喜欢:两种方法只有一个限定符。我将稍后再试。我编辑了@Qualifier annotation上我提到的帖子,作为处理此问题的首选方法。谢谢,我刚刚用代码片段添加了我的答案