В spring bean возможно ли иметь метод выключения, который может использовать транзакции?
В методе уничтожения spring bean я хочу выполнить некоторые запросы для очистки некоторых вещей в базе данных. spring, похоже, не позволяет это каким-либо образом найти.
Ошибка всегда есть что-то вроде:
Вызов метода уничтожения bean с именем "someBean": org.springframework.beans.factory.BeanCreationNotAllowedException: Ошибка при создании bean с именем 'transactionManager': Singleton beanсоздание не допускается, пока синглтоны этого factory находятся в уничтожение (не запрашивать beanиз BeanFactory в методе уничтожения реализация!)
Следующее сообщит spring, чтобы вызвать shutdownDestroy после того, как bean больше не нужен. Но при попытке использовать транзакции я получаю вышеуказанную ошибку.
<bean id="someId" name="someName" class="someClass"
destroy-method="shutdownDestroy"/>
То же самое верно, когда я включаю общие аннотации жизненного цикла, используя:
<bean class="org.springframework. ... .CommonAnnotationBeanPostProcessor"/>
а затем отметьте метод @PreDestroy
. Этот метод также не может использовать транзакции.
Есть ли способ сделать это?
EDIT:
Благодарю! У меня был bean реализовать SmartLifecycle и добавить следующее, и он работает очень хорошо.
private boolean isRunning = false;
@Override
public boolean isAutoStartup() {return true;}
@Override
public boolean isRunning() {return isRunning;}
/** Run as early as possible so the shutdown method can still use transactions. */
@Override
public int getPhase() {return Integer.MIN_VALUE;}
@Override
public void start() {isRunning = true;}
@Override
public void stop(Runnable callback) {
shutdownDestroy();
isRunning = false;
callback.run();
}
@Override
public void stop() {
shutdownDestroy();
isRunning = false;
}
Ответы
Ответ 1
Интересный вопрос. Я бы сказал, что вы сможете это сделать чтобы ваш bean реализовал SmartLifeCycle
.
Таким образом, если ваш метод int getPhase();
возвращает Integer.MAX_VALUE
, он будет одним из первых, который будет вызываться, когда ApplicationContext
окончательно выключится.
Справка:
Ответ 2
Я сталкиваюсь с этой же проблемой. После проверки исходного кода spring U может попытаться реализовать
public class SomeBean implements ApplicationListener<ContextClosedEvent> {
public void onApplicationEvent(ContextClosedEvent event) {
stopHook();
}
}
onApplicationEvent будет вызван до bean destory, вы можете проверить его на spring org.springframework.context.support.AbstractApplicationContext # doClose. Я вставляю его ниже, поэтому ContextEvent → LifeCycle → bean destory.
try {
// Publish shutdown event.
publishEvent(new ContextClosedEvent(this));
}
catch (Throwable ex) {
logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);
}
// Stop all Lifecycle beans, to avoid delays during individual destruction.
try {
getLifecycleProcessor().onClose();
}
catch (Throwable ex) {
logger.warn("Exception thrown from LifecycleProcessor on context close", ex);
}
// Destroy all cached singletons in the context BeanFactory.
destroyBeans();
// Close the state of this context itself.
closeBeanFactory();
// Let subclasses do some final clean-up if they wish...
onClose();