gpt4 book ai didi

java - CDI 传递服务的最佳方式

转载 作者:行者123 更新时间:2023-11-30 06:04:25 24 4
gpt4 key购买 nike

我有几个这样的服务:

@Singleton
public SimpleService {
...
}

我有托管 Bean @ViewScoped,它应该创建一些复杂的对象。这些对象应该执行业务逻辑。我需要将这些服务传递给这个对象。

托管 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注解注入(inject)到Managed Bean中。为了创建这些对象——我使用构造函数并将这些服务作为参数传递。问题是:我能有比在构造函数中传递服务更好的解决方案吗?

最佳答案

您可以:

  • 通过方法注入(inject):
    private MyService myService;    @Inject    public void setMyService(MyService ms) {        this.myService = ms;    }
  • Inject by field:
    @Inject    private MyService myService;   
  • Fetch reference through CDI (not recommended, except in advanced usecases):
    ...    MyService myService = CDI.current().select(MyService.class).get();    ...
  • Fetch reference through BeanManager (not recommended, except in advanced usecases or CDI 1.0):
    ...    BeanManager beanManager = CDI.getBeanManager(); // you can fetch a BeanManager reference by several other methods, I use CDI for simplicity here    MyService myService = beanManager.getReference(MyService.class);    ...
  • If your @Singleton annotation is javax.ejb.Singleton and not javax.inject.Singleton, then your bean is actually a EJB and you can also use any mechanism that allows you to access EJB, such as @Resource annotations, or through the JNDI context.

Personally I tend to inject by method as I find it the most flexible option most of the time. In my opinion it is also the most "portable" to other frameworks (e.g: Spring)

Remember that when you use either the CDI.current() or the BeanManager methods to fetch @Dependent beans, you are responsible to manually destroy the fetched bean when you are done with it, so that you do not fall into this CDI-related memory leak. When using CDI.current() it is as easy as saving the Instance reference and invoking it afterwards:

...
Instance<MyService> msInstance = CDI.current().select(MyService.class);
MyService myService = msInstance.get();
...
msInstance.destroy(myService);
...

BeanManager 方法太底层,只能在 CDI 1.0 环境中使用(回到 CDI 类还不存在的时候)。您可以阅读链接的 StackOverflow 问题以了解更多详细信息。

关于java - CDI 传递服务的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49529741/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com