Вопрос по spring – Как вызвать метод после завершения инициализации компонента?

216

У меня есть случай, когда мне нужно вызывать (нестатический) метод в компоненте только один раз при загрузке ApplicationContext. Это нормально, если я использую MethodInvokingFactoryBean для этого? Или у нас есть лучшее решение?

Как примечание, я использую ConfigContextLoaderListener для загрузки контекста приложения в веб-приложении. И хотите, чтобы, если экземпляр E был создан, просто вызовите methodA () один раз.

Как это можно сделать красиво?

Ваш Ответ

6   ответов
-7

т. Е. Использования

@PostConstruct а такжinit-method="init"

Из личного опыта я понял, что использование (1) работает только в контейнере сервлетов, в то время как (2) работает в любой среде, даже в настольных приложениях. Таким образом, если вы будете использовать Spring в автономном приложении, вам придется использовать (2), чтобы выполнить «вызов этого метода после инициализации.

Технически,@PostConstruct (при использовании в приложении на основе Spring) связано с продолжительностью жизни собственного контекста Spring. Такие контексты могут использоваться во всех видах приложений. Donal Fellows
Такое поведение я ожидал, но у меня не получилось. Ayorinde
193

Вы можете использовать что-то вроде:

<beans>
    <bean id="myBean" class="..." init-method="init"/>
</beans>

Это вызовет метод init при создании экземпляра компонент

postConstruct должен быть лучше в большинстве случаев, так как мы не хотим путаться с инициализацией bean-компонент lwpro2
Спасибо, я действительно искал что-то вроде новичка в Spring. Gondy
@ lwpro2 Что вы подразумеваете под «не хотите портить весенние бины» здесь? Yngve Sneen Lindal
@ Mercer Traieste что я должен дать для атрибута класса здесь? Могу ли я дать класс контроллера здесь? KJEjava48
292

на мой взгляд, это действительно лучшее решение.

Он сохраняет ваш код отделенным от Spring API (@PostConstruct находится в javax. *) Он явно аннотирует ваш метод init как то, что нужно вызвать для инициализации bean-компонента Вам не нужно помнить, чтобы добавить атрибут init-method к определению вашего bean-компонента Spring, spring автоматически вызовет метод (в любом случае, если вы зарегистрируете опцию annotation-config где-нибудь еще в контексте).
Не знал о @PostConstruct, пока не прочитал этот пост. Выручил меня, так что спасибо. AHungerArtist
Спасибо, это работает. Обратите внимание: если вы хотите использовать Spring, вы должны включить «<context: annotation-config />» для регистрации bean-компонента CommonAnnotationBeanPostProcessor (как упоминалось выше) khylo
Подходящий<context:component-scan> также работает и может быть полезен для сокращения времени запуска, если в вашем пути к классам есть большие библиотеки, отличные от Spring. Donal Fellows
JavaDoc для PostConstruct говорит, что только один метод может быть аннотирован с ним на класс: Docs.oracle.com / JavaEE / 5 / API / javax / аннотаций / ... Andrew Swan
@ PostConstruct также не очень пригодится вам, когда создаваемый вами компонент - это не ваш собственный класс, а какой-то сторонний класс John Rix
96

ссылк

Используйте атрибут init-методаPros: Не требует bean-компонента для реализации интерфейса.Cons: Нет немедленного указания, что этот метод необходим после построения, чтобы убедиться, что компонент настроен правильно.Implement InitializingBeanPros: Нет необходимости указывать init-метод или включать компонентное сканирование / обработку аннотаций. Подходит для bean-компонентов, поставляемых с библиотекой, где мы не хотим, чтобы приложение, использующее эту библиотеку, занималось жизненным циклом bean-компонента.Cons: Более инвазивен, чем метод init-метода. Используйте JSR-250@ PostConstruct аннотация жизненного циклаPros: Полезно при использовании компонентного сканирования для автоматического определения бинов. Дает понять, что для инициализации должен использоваться определенный метод. Намерение ближе к коду.Cons: Инициализация больше не указывается централизованно в конфигурации. Не забудьте включить обработку аннотаций (о которой иногда можно забыть)
Я думаю, что на самом деле это хорошая вещь, чтобы использовать@PostConstruct именно потому, что он является частью класса, который нуждается в вызове метода в конце обработки инициализации. Donal Fellows
Если этому классу ДЕЙСТВИТЕЛЬНО это нужно, и вы не можете сделать это в конструкторе, я считаю, что это запах кода. user482745
37

InitializingBean? Это звучит как то, что вы после.

Недостатком является то, что ваш бин становится осведомленным о Spring, но в большинстве приложений это не так уж и плохо.

Есть ли причина, по которой вы бы выбрали реализацию интерфейса вместо указания метода init в XML? Mark
Это дело вкуса. Интерфейс является частью модели компонентов Spring и служит этой и только этой цели, в то время как для пользовательского именованного метода может быть не совсем очевидно, что его нужно вызывать для завершения жизненного цикла компонента. Так что это служит общению в основном. Конечно, с недостатком введенной зависимости от среды Spring. Хорошим способом между ними является использование @PostConstruct, так как он имеет четкую семантику, но не вводит зависимости ... Oliver Drotbohm
Oliver дает мне несколько хороших оправданий, но на самом деле я просто забыл о init-методе :) Еще одна причина в том, что сам тип знает, что его нужно «завершить» после того, как все свойства были установлены - это не так. т в основном то, чтодолже быть в конфигурации. Jon Skeet
8

BeanPostProcessor в контексте вашего приложения, чтобы сделать это. Или, если вы не возражаете против реализации интерфейса Spring в вашем бине, вы можете использовать InitializingBean interface или директива init-method (та же ссылка).

У кого-нибудь есть подробности о том, как написать BeanPostProcessor. Это звучит как раз то, что мне нужно. Ура peakit
Spring поставляется со многими примерами. Просто посмотрите на API JavaDoc для BeanPostProcessor, и вы найдете ссылки на многие реализующие классы. Тогда посмотрите на исходный код для них. Rob H

Похожие вопросы