【发布时间】:2019-04-21 21:54:00
【问题描述】:
我有两个托管 Java bean:
import javax.annotation.PostConstruct;
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.ws.rs.Path;
@Path("/sync")
@ManagedBean(name="syncService", eager=true)
@ApplicationScoped
public class SyncService {
@ManagedProperty(value="#{ldapDirectoryAccess}")
private DirectoryAccess directoryAccess;
public void setDirectoryAccess(DirectoryAccess directoryAccess) {
System.out.println("SyncService.setDirectoryAccess()");
this.directoryAccess = directoryAccess;
}
public SyncService() {
System.out.println("SyncService() - constructed: " + this);
}
@PostConstruct
public void init() {
System.out.println("DirectoryAccess injected: " + directoryAccess + " in: " + this);
}
...
}
@ManagedBean(name="ldapDirectoryAccess", eager=true)
@ApplicationScoped
public class LdapDirectoryAccess implements DirectoryAccess {
public LdapDirectoryAccess() {
System.out.println("LdapDirectoryAccess constructed: " + this);
}
...
}
当我在 Tomcat 中部署应用程序时,我在 catalina.out 中得到以下输出:
SyncService() - constructed: ...SyncService@705ebb4d
...
LdapDirectoryAccess constructed: ...LdapDirectoryAccess@3c1fd5aa
SyncService.setDirectoryAccess()
DirectoryAccess injected: ...LdapDirectoryAccess@3c1fd5aa in:
...SyncService@705ebb4d
LdapDirectoryAccess constructed: ...LdapDirectoryAccess@59d6a4d1
因此,首先按预期构造每个 bean 的实例,然后将第二个 bean 注入第一个。但是随后,创建了第二个 bean 类的另一个实例。这怎么可能?在this tutorial 我发现了以下内容:
@ApplicationScoped
只要 Web 应用程序存在,Bean 就会存在。它被创建于 应用程序中涉及此 bean 的第一个 HTTP 请求(或当 Web 应用程序启动并设置了 eager=true 属性 @ManagedBean) 并在 Web 应用程序关闭时被销毁。
所以我希望每个 bean 的一个实例在应用程序启动时创建,而这两个实例在应用程序关闭时都被销毁。但是LdapDirectoryAccess 被构造了两次。
此外,当我打开SyncService 提供的页面时,我看到:
SyncService() - constructed: ... SyncService@1cb4a09c
所以SyncService 的第二个实例也被构建了,我不明白为什么。还有,这次没有注入directoryAccess属性,服务抛出空指针异常。
这意味着SyncService 的第一个实例是正确构建的,但是随后
-
SyncService的第二个实例被创建(为什么?) - 没有
LdapDirectoryAccess注入其中(为什么?) -
SyncService的第二个实例用于提供对我的 REST API 的调用。为什么是这个实例而不是第一个创建的实例?
不过,我查看了this question 及其答案:
- 我正在使用 Mojarra 2.2.18
- 我的应用程序的
web.xml不包含任何提及com.sun.faces.config.ConfigureListener的标签
所以经过几个小时的调查,我完全没有想法。你有什么提示吗?
【问题讨论】:
标签: jsf dependency-injection managed-bean