清洁的解决方案,用于急切的CDI bean实例化

时间:2017-09-22 09:40:33

标签: java-ee cdi weld

想象一下以下简化的DI模型:

@ApplicationScoped
public class A {

    private B b;

    @Inject
    public A(B b) {
        this.B = b;
    }

}

@ApplicationScoped
public class B {

    private C c;

    @Inject
    public B(C c) {
        this.C = c;
    }

}

@ApplicationScoped
public class C {

    @PostConstruct
    public void start() {
        // processing that should begin on startup
    }

}

假设我希望在部署完成时调用C#start。通常在线建议的模式是here,但解决方案:1)添加太多样板,2)为扩展添加新的文本文件,3)使用{{1}的作弊单独触发toString代理实例化下面的实际B bean,然后触发B代理等。

从CDI 1.1开始,将以下方法添加到C也是一种解决方案:

A

这解决了上面描述的前两个问题,但我仍然需要在public void init(@Observes @Initialized(ApplicationScoped.class) Object init) { B.toString(); } 上调用一个虚方法,以便触发实例化/注入链并最终调用B带注释的方法{{ 1}}。

我错过了这个问题的清洁解决方案吗? CDI 2.0能解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

您无法选择急切初始化,您必须选择一些“解决方法”。 CDI没有定义bean init是懒惰还是渴望,而且懒惰在大多数时候都更有意义,Weld也是这样。

您最好的选择与article you mentioned建议的类似。例如。设置一个扩展,樱桃挑选你想要急切初始化的bean并初始化它们并加上一个(无害的)方法。

显然,这只适用于部署中的几个bean(我认为最多使用应用程序范围的bean),因此开销不会太大(如果有的话)。还有一些额外的样板,但是你不必写那么多行就可以了。

为了使它更好,您可以让所有bean使用默认的ping()方法实现虚拟接口,并从扩展中调用该方法 - 只是为了避免调用toString()