Почему конструктор класса CDI bean вызывается несколько раз
Я аннотировал класс с помощью @ApplicationScoped. С помощью @Inject я получаю экземпляры этого класса, внедренные в несколько служб @RequestScopded JAX-RS:
@ApplicationScoped
public class MySingleton {
MySingleton() {
System.out(this + " created.");
}
}
@RequestScoped
public class MyRS {
@Inject MySingleton mySingleton;
public void someMethod() {
// do something with mySingleton
}
}
В основном это работает нормально. Howeger, по крайней мере, когда я запускаю это в WebSphere 8.5, конструктор MySingleton вызывается дважды, в результате чего выводится как
my.package.MySingleton_$$_javassist_26@cddebf9b created.
my.package.MySingleton@e51e26d1 created.
Я планировал сделать какую-то дорогостоящую инициализацию в конструкторе, которая, очевидно, будет выполнена дважды.
Я полагаю, что один из вызовы конструктора предназначены для создания некоторого прокси-сервера для фактического экземпляра "worker". Но как я могу избежать того, чтобы мой код инициализации выполнялся дважды? "Решение" сделать ленивую инициализацию во всех методах MySingleton не очень привлекательно.
2 ответа:
Конструктор управляемых бобов может быть вызван контейнером также для создания прокси-серверов. Поэтому для любой "реальной" инициализации Java EE предоставляет аннотацию @PostConstruct. В бобе @ApplicationScoped метод с аннотацией @PostConstruct вызывается контейнером ровно один раз:
@ApplicationScoped public class MySingleton { MySingleton() { System.out(this + " created."); } @PostConstruct init() { System.out(this + " initd."); } }
Вывод:
my.package.MySingleton_$$_javassist_26@cddebf9b created. my.package.MySingleton@e51e26d1 created. my.package.MySingleton@e51e26d1 initd.
Связанный Вопрос: зачем использовать @PostConstruct?