CDI 注入样式

CDI injection styles

我读到我可以通过 3 种不同的方式注入 bean:

我一直使用第一种样式,我不知道何时以及为何使用其他两种。我找到了使用构造函数注入 here 的原因,当它说它让 class 成为 immutable.

任何人都可以向我展示这些注入样式的有用示例吗?

第一个简短。任何特定的 CDI 驱动的应用程序都是一个例子。

当您的方法对类型与注入字段的类型匹配的对象进行操作时,第二个会派上用场。一个例子是:

public class Garage {
    private final Car expected;
    private final List<Car> cars = new LinkedList<>();

    @Inject
    public Garage(@CarEtalon Car expected) { 
        this.expected = expected;
    }

    public void add(Collection<Car> toAdd) {
        Car expectsCheck = null;
        for (Iterator<Car> i = toAdd.iterator(); i.hasNext(); ) {
            // Due to an autocomplete issue, you've made a typo...
            expected = iterator.next();
            // and your class could've been broken by a simple typo,
            // but since our logical data model is reflected in code
            // by using 'final' keyword, compiler will stop us here.
            if (expected.matches(expectsCheck)) {
                cars.add(expectsCheck);
            }
        }
    }
}

这个例子很综合,但很好地反映了这个想法。 POJO 改编(具有 XML 描述符)可能会利用这种实例化,因为基于构造函数的初始化在 SE 世界中更受欢迎。

后一种情况很少见。要注入的具有可变字段的可变对象很奇怪,但它可能会派上用场。例如:

  1. 这样的注入有时用于有状态和 SessionScoped bean 来为其可写属性提供合理的默认值。
  2. 当对象需要进行单元测试并且有很多依赖项时也会使用这种情况(JSF backing beans 可能是一个原始的例子)。基于构造函数的 10 个 bean 注入可能最终会编写成吨的样板代码,而基于 setter 的注入可能是一种合理的折衷方案。
  3. 如果 POJO 没有合适的构造函数,针对托管环境的 POJO 适配可能会以基于 setter 的注入结束。