【问题标题】:CDI best way for passing servicesCDI 传递服务的最佳方式
【发布时间】:2018-03-28 08:35:47
【问题描述】:

我有几个这样的服务:

@Singleton
public SimpleService {
    ...
}

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

【问题讨论】:

  • 在 IoC 环境中,您必须将数据与服务分离。你需要有build你的数据的可注入组件。
  • 不清楚你是如何使用你的注入的,你能把那部分代码贴出来吗?
  • @maress,谢谢,将审查我创建可注射组件的逻辑
  • @prmottajr 用于向托管 Bean 注入服务,我有以下代码:ManagedBean public class ManagedBean {Inject SimpleService service;}
  • @Трубецкой 使用注入应该足够了,这就是使用 CDI 的重点,如果您可以编辑问题并添加您正在使用的代码,您不需要将这些对象传递给构造函数传递参数会有所帮助。

标签: java jakarta-ee cdi


【解决方案1】:

你可以:

  • 按方法注入:
私人的我的服务我的服务; @注入 公共无效setMyService(我的服务毫秒){ 这个.myService = ms; }
  • 按字段注入:
@注入 私人的我的服务我的服务;
  • 通过CDI 获取引用(不推荐,除非在高级用例中):
... MyService myService = CDI.current().select(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 时,您有责任在完成后手动销毁获取的 bean,所以你不属于this CDI-related memory leak。使用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。
  • @Трубецкой 编辑问题后,我发现我的答案实际上有点离题。仅供参考,prmottajr 的答案看起来恰到好处。
【解决方案2】:

您所做的一切都很好。您使用 ManagedBean 作为桥梁来注入服务,然后将注入的变量传递给需要服务的 ComplexObject。

应该考虑的唯一限制是,ComplexObject 类本身可以是 ManagedBean 吗?这样你可以直接在上面注入所有东西,但如果不可能,你可以使用 bean。

我更喜欢提到的按字段注入选项,因为我认为它更具可读性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-19
    • 1970-01-01
    相关资源
    最近更新 更多