CDI通过服务的最佳方法



我有几种这样的服务:

@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为此。

我更喜欢提到的登录选项,因为我认为它更可读性。

相关内容

最新更新