У меня есть два управляемых Java-бина:
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
Итак, сначала создается экземпляр каждого компонента, как и ожидалось, а второй компонент вводится в первый. Но затем создается другой экземпляр второго класса бинов. Как это возможно? В этом уроке я нашел следующее:
@ ApplicationScoped
Бин живет столько, сколько живет веб-приложение. Это создается на
первый HTTP-запрос, включающий этот компонент в приложении (или когда
веб-приложение запускается, и атрибут eager = true устанавливается в
@ManagedBean) и уничтожается при закрытии веб-приложения.
Таким образом, я ожидал, что один экземпляр каждого компонента создается при запуске приложения, и оба экземпляра уничтожаются при завершении работы приложения. Но LdapDirectoryAccess
строится дважды.
Более того, когда я открываю страницу, обслуживаемую SyncService
, я вижу:
SyncService() - constructed: ... SyncService@1cb4a09c
поэтому второй экземпляр SyncService
также построен, и я не могу понять, почему. Кроме того, на этот раз свойство directoryAccess
не вводится, и служба генерирует исключение нулевого указателя.
Это означает, что первый экземпляр SyncService
построен правильно, но затем
- Создается второй экземпляр
SyncService
(почему?)
- Нет
LdapDirectoryAccess
вводится в него (почему?)
- Этот второй экземпляр
SyncService
используется для обслуживания вызова моего REST API. Почему этот экземпляр, а не первый, который был создан?
Я посмотрел на этот вопрос и его ответы, однако:
- Я использую Мохарру 2.2.18
- В моем приложении
web.xml
нет тегов с упоминанием com.sun.faces.config.ConfigureListener
Так что я после нескольких часов расследования у меня совершенно нет идей. У вас есть какие-нибудь подсказки?