2013-08-22 2 views
3

Я аннотировал класс с @ApplicationScoped. С @Inject я получаю экземпляры этого класса инжектированных в несколько @RequestScopded услуг JAX-RS:Почему конструктор класса бина CDI называется более одного раза

@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 вызывается дважды, что приводит к выходу, как

[email protected] created. 
[email protected] created. 

Я планировал сделать некоторые дорогие инициализации в конструкторе, который, очевидно, будет выполнен в два раза.

Я считаю, что один из вызовов конструктора предназначен для создания своего рода прокси-сервера для фактического экземпляра «рабочий». Но как я могу избежать выполнения кода инициализации, выполняемого дважды? «Решение» для ленивой инициализации во всех методах MySingleton не очень привлекательно.

+0

Просто ослепить гадать, но попытаться использовать @ PostConstruct, чтобы узнать, будет ли он дважды вызываться. –

+0

@@ PostConstruct вызывается только один раз, и это именно то, что мне нужно. С этим намеком я также нашел связанный вопрос [why-use-postconstruct]. Если вы опубликуете это как ответ, я приму это. Спасибо, @Adrian. –

+0

Вы должны использовать интерфейсы вместо конкретных классов для ввода. –

ответ

6

Конструктор управляемых компонентов может быть вызван контейнером также для создания прокси. Для любой «реальной» инициализации Java EE поэтому предоставляет аннотацию @PostConstruct. В @ApplicationScoped боб метод с аннотацией @PostConstruct вызывается ровно один раз контейнером:

@ApplicationScoped 
public class MySingleton { 
    MySingleton() { 
    System.out(this + " created."); 
    } 
    @PostConstruct 
    init() { 
    System.out(this + " initd."); 
    } 
} 

Выход:

[email protected] created. 
[email protected] created. 
[email protected] initd. 

Связанные вопрос: Why use @PostConstruct?

0

Это прокси-объект javassist, созданный для вашего синглтона. Контрактор singleton должен просто вызываться, когда создается фактический объект.

Смежные вопросы