我在 JBoss EAP 6.0.1 中有(简约版本)以下 CDI 托管 bean

@ApplicationScoped
public class Outer {
    private final List<String> values = new ArrayList<String>();

    public void printValues() {
        System.out.println("Values: " + values);
    }

    private void addValue(String value) {
        values.add(value);
    }

    public static class Inner {

        @Inject
        private Outer outer;

        public void addFoo() {
            outer.addValue("foo");
        }
    }
}

并使用以下代码来测试这一点(不要问为什么。仅适用于本次展示。):

@Inject
Outer outer;

@Inject
Outer.Inner inner;

public void test() {
    inner.addFoo();
    outer.printValues();
}

我得到的输出是:

Values: {}

我本来期望值 foo.

进一步调查显示,该电话 private void addValue 访问一个版本 values 位于 Weld 生成的代理中的属性 Outer 而调用 public void printValues 访问真实托管 Bean 实例的真实属性。

让事情变得更加混乱:如果我更改访问级别 addValue 到其中之一 package, protected 或者 public 一切都按预期进行。

但在我的例子中,内部类的目的是使该方法成为私有的,以便 Outer 的其他 CDI 客户端无法调用该方法。现在这是唯一不起作用的事情:D

知道出了什么问题吗?这是 Weld 中的错误吗?

有帮助吗?

解决方案

目前,所有 CDI 提供程序都使用代理(规范中不要求这样做,但这就是所有三个 impl 的完成方式)来注入任何非伪作用域对象。如果外层是 @DependantScoped 我很确定它会按照您想要的方式工作。创建的代理自然是类的子类,因此在注入的对象上调用私有方法是行不通的。老实说,我很惊讶它没有爆炸。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top