我有几种这样的服务:
@Singleton
public SimpleService {
...
}
我管理了BEAN @ViewScoped,该bean应该创建一些复杂的对象。这些对象应执行业务逻辑。我需要将这些服务传递给此对象。
托管bean的示例:
@ManagedBean
@ViewScoped
public class ExampleBean {
@Inject
private SimpleService simpleService;
...
public void customLogic() {
// in this method I should create complex object which should have services and some data.
// current implementation
ComplexObject object = new ComplexObject(SimpleService simpleService, ...)
}
}
服务通过@Inject注释注入托管bean。为了创建这些对象 - 我正在使用构造函数并将这些服务作为参数传递。问题是:我可以比通过构造函数传递服务更好的解决方案吗?
您可以:
- 通过方法注入:
私人MyService MyService; @注入 public void setMyservice(MyService MS({ this.myservice = ms; }
- 通过字段注入:
@注入 私人MyService MyService;
- 通过
CDI
提取参考(不推荐,除了高级用户酶以外(:
... myService myService = cdi.current((。选择(myService.class(.get((; ...
- 通过
BeanManager
提取参考(不推荐,除了高级用途或CDI 1.0(:
... beanmanager beanmanager = cdi.getBeanManager((;//您可以通过其他几种方法获取BeanManager参考,我在此处使用CDI为简单起见 myService myService = beanmanager.getReference(myService.Class(; ...
- 如果您的
@Singleton
注释是javax.ejb.Singleton
而不是javax.inject.Singleton
,则您的Bean实际上是EJB,您还可以使用任何允许您访问EJB的机制,例如@Resource
注释,或通过JNDI上下文。
我个人倾向于通过方法注入,因为我在大多数时候都发现它是最灵活的选项。我认为,它也是其他框架(例如:Spring(
的最"便携式">请记住,当您使用 CDI.current()
或 BeanManager
方法获取 @Dependent
bean时,您负责手动销毁完成它后,您就不会掉入此与CDI相关的内存泄漏。使用CDI.current()
时,与保存Instance
参考并随后调用它一样容易:
...
Instance<MyService> msInstance = CDI.current().select(MyService.class);
MyService myService = msInstance.get();
...
msInstance.destroy(myService);
...
BeanManager
方法太低级别,仅应在CDI 1.0环境中使用(当CDI
类还不存在时返回(。您可以阅读链接的stackoverflow问题以获取更多详细信息。
您正在做的事情很好。您正在使用托管Bean作为桥梁注入服务,然后将注入的变量传递给需要服务的复杂对象。
应考虑的唯一限制是,复杂对象类别可以是托管本身吗?这样,您可以将所有内容直接注入其中,但是如果不可能,则可以使用bean为此。
我更喜欢提到的登录选项,因为我认为它更可读性。