领域
为什么我需要这些无参数构造函数?
*如果会话范围的 bean 被注入到应用程序范围的 bean 中会发生什么?应用程序作用域 bean 如何为每个请求获取正确的会话范围 bean 实例?会话范围内的 bean 不会泄漏到其他请求中吗?这是如何运作的?*为了便于确定范围,CDI 使用所谓的代理。当 CDI 将非依赖的 scoped bean 注入另一个对象时,它不会直接注入 bean。相反,它将该 bean 子类化以创建所谓的代理。每当在代理上调用一个方法时,它都会要求 CDI 运行时查找该特定范围的正确 bean(如果它的请求作用域,则获取该请求的 bean。如果它是会话作用域,则获取该会话的 bean。等等。),然后将调用转发给真实对象,返回非 void 方法的任何结果。这意味着以下是可以做的事情:
@ApplicationScoped
public class ApplicationScopedClass {
private final RequestScopedClass requestScopedClass;
@Inject
public ApplicationScopedClass(RequestScopedClass requestScopedClass) {
this.requestScopedClass = requestScopedClass;
}
public ApplicationScopedClass() {
}
public doSomething() {
requestScopedClass.doSomethingRequestSpecific(); //This works, because of the proxy
}
}
但是,为了使类在 Java 中合法地子类化另一个类,它必须具有有效的构造函数。并且有效的构造函数必须调用类上的另一个构造函数或父类的构造函数(例如 super()
)。为了简化这个子类,CDI 规范要求任何非依赖的 scoped bean 提供一个公共的无参数构造函数,这样运行时就不必试着猜测如何处理需要代理的类。。