Есть ли какая-нибудь особенность Spring 3 для выполнения некоторых методов при первом запуске приложения? Я знаю, что могу сделать метод установки метода с @Scheduled
аннотацией, и он выполняется сразу после запуска, но затем он будет выполняться периодически.
176
Ответы:
Если под «запуском приложения» вы подразумеваете «запуск контекста приложения», то да, есть много способов сделать это , самый простой (в любом случае, для bean-компонентов синглтонов) состоит в том, чтобы аннотировать ваш метод
@PostConstruct
. Взгляните на ссылку, чтобы увидеть другие варианты, но в итоге они:@PostConstruct
afterPropertiesSet()
как определеноInitializingBean
интерфейсом обратного вызоваТехнически, это крюки в жизненном цикле бина , а не в жизненном цикле контекста, но в 99% случаев они эквивалентны.
Если вам нужно специально подключиться к контексту при запуске / завершении работы, вы можете вместо этого реализовать
Lifecycle
интерфейс , но это, вероятно, не нужно.источник
Access restriction: The type PostConstruct is not accessible due to restriction on required library /Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/jre/lib/rt.jar
@PostConstruct
был вызван его метод, но инфраструктура JMS, от которой он косвенно зависел, еще не была полностью подключена (а в Spring все просто молчаливо провалилось). При переключении на@EventListener(ApplicationReadyEvent.class)
все работало (ApplicationReadyEvent
специфичен ли Spring Boot для ванильной Spring, см. Ответ Стефана).Это легко сделать с помощью
ApplicationListener
. Я получил это на работу, слушая SpringContextRefreshedEvent
:Слушатели приложений работают синхронно в Spring. Если вы хотите убедиться, что ваш код выполняется только один раз, просто сохраните некоторое состояние в вашем компоненте.
ОБНОВИТЬ
Начиная с Spring 4.2+, вы также можете использовать
@EventListener
аннотацию для наблюденияContextRefreshedEvent
(спасибо @bphilipnyc за это):источник
ContextStartedEvent
вместо этого, сложнее добавить слушателя до того, как событие сработает.В Spring 4.2+ вы можете теперь просто сделать:
источник
Если вы используете spring-boot, это лучший ответ.
Я чувствую, что
@PostConstruct
и другие разнообразные междометия в жизненном цикле обходные пути. Это может привести непосредственно к проблемам во время выполнения или вызвать менее очевидные дефекты из-за непредвиденных событий жизненного цикла bean / context. Почему бы просто не напрямую вызывать ваш компонент с помощью простой Java? Вы по-прежнему вызываете бин «пружинным путем» (например, через прокси AoP пружины). И что самое приятное, это просто Java, проще не бывает. Нет необходимости в прослушивателях контекста или нечетных планировщиках.источник
main()
, например, при использовании инфраструктуры приложения (например, JavaServer Faces).Для пользователей Java 1.8, которые получают предупреждение при попытке сослаться на аннотацию @PostConstruct, я в итоге вместо этого воспользовался аннотацией @Scheduled, которую вы можете сделать, если у вас уже есть задание @Scheduled с fixedRate или fixedDelay.
источник
Что мы сделали, так это распространили
org.springframework.web.context.ContextLoaderListener
что-то, когда начинается контекст.Настройте подкласс затем в
web.xml
:источник
С SpringBoot мы можем выполнить метод при запуске через
@EventListener
аннотациюисточник
Вы также можете использовать запланированный метод с фиксированным установленным значением очень высокого
Преимущество заключается в том, что все приложение подключено (транзакции, дао, ...)
видно в разделе Планирование задач для однократного запуска с использованием пространства имен задач Spring
источник
@PostConstruct
?Опубликовал другое решение, которое реализует WebApplicationInitializer и вызывается задолго до того, как будет создан экземпляр любого bean-компонента, в случае, если у кого-то есть такой вариант использования
Инициализация локали и часового пояса по умолчанию с конфигурацией Spring
источник
источник
Если вы хотите настроить bean-компонент до того, как ваше приложение будет полностью запущено, вы можете использовать
@Autowired
:источник
Вы можете использовать
@EventListener
в своем компоненте, который будет вызываться после запуска сервера и инициализации всех bean-компонентов.источник
Для файла,
StartupHousekeeper.java
расположенного в пакетеcom.app.startup
,Сделайте это в
StartupHousekeeper.java
:И сделать это в
myDispatcher-servlet.java
:источник