2011-12-29 3 views
4

Предположим, что у меня есть классы обслуживания Spring или JSF beans. Я провожу эти классы в другом классе. Проблем до сих пор нет. Я могу использовать эти введенные поля любым способом.Зависимость впрыска в конструкторе

Но, используя их в конструкторе, я получаю исключение NullPointerException.

Возможно, конструктор работает до того, как произойдет инъекция зависимости, и он не видит мои введенные поля. Есть ли какое-либо решение для использования инъекции зависимостей в конструкторе?

ответ

3

Очевидно, что невозможно вставить что-либо в объект, если этот объект не существует. И чтобы существовать, объект должен быть построен.

Пружина поддерживает внедрение конструктора:

@Autowired 
public SomeService(SomeDependency dep) { 
    ... 

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

Не знаю, что такое JSF.

+1

Ну ['@ PostConstruct'] (http://docs.oracle.com/javase/6/docs /api/javax/annotation/PostConstruct.html) является аннотацией EJB, поэтому она явно поддерживается в JavaEE. И ['@ Ìnject'] (http://docs.oracle.com/javaee/6/api/javax/inject/Inject.html) применим и к конструкторам. –

+0

@Sean: это не аннотация EJB. Это часть Java SE API. Но это действительно видно в комбинации с EJB. – BalusC

+0

@BalusC формально, что может быть правдой, но в документации явно упоминается спецификация EJB. –

3

Нет, вы не можете ссылаться на введенные поля в конструкторе. Структура должна каким-то образом построить ваш объект (вызвать конструктор), а затем ввести зависимости, чтобы они были пустыми во время выполнения конструктора. Что вы обычно делаете, а не применяет @PostConstruct аннотацию к одному из ваших методов и выполнить инициализацию там:

class MyBean { 
    @Inject 
    private MyDependency myDep; 

    @PostConstruct 
    public void init() { 
    assert myDep != null; 
    } 
} 

В случае конфигурации пружины XML вы можете использовать init-method="init" вместо @PostConstruct в вашем <bean> определения. В качестве альтернативы вы можете использовать инъекцию конструктора в xml:

<bean id="myBean" class="my.package.MyBean"> 
    <constructor-arg ref="myDependency/> 
</bean> 

или эквивалент аннотации.

+0

Да, использование @postConstruct может быть решением вместо использования конструктора –

+0

В качестве дополнительного факта, '@ PostConstruct' может использоваться даже при' private' init методе. Установка метода init для частной видимости может быть полезна для использования чистого, незагроможденного публичного API. (см. http://docs.oracle.com/javaee/6/api/javax/annotation/PostConstruct.html) – Abdull

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