在spring bean的destroy方法中,我想执行一些查询来清理数据库中的一些东西。 Spring似乎无法以任何方式找到它。
错误总是如下:
调用destroy方法失败 名为'someBean'的bean: org.springframework.beans.factory.BeanCreationNotAllowedException: 使用名称创建bean时出错 'transactionManager':单例bean 创造不允许的时候 这家工厂的单身人士都在 破坏(不要求bean 来自destroy方法中的BeanFactory 实施!)
以下将告诉spring在不再需要bean之后调用shutdownDestroy。但是,我在尝试使用事务时遇到上述错误。
<bean id="someId" name="someName" class="someClass"
destroy-method="shutdownDestroy"/>
使用以下命令启用公共生命周期注释时也是如此:
<bean class="org.springframework. ... .CommonAnnotationBeanPostProcessor"/>
然后使用@PreDestroy
标记方法。该方法也不能使用交易。
有没有办法做到这一点?
编辑: 谢谢!我有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;
}
答案 0 :(得分:14)
有趣的问题。我会说你应该可以通过letting your bean implement SmartLifeCycle
来做到这一点。
这样,如果您的int getPhase();
方法返回Integer.MAX_VALUE
,那么当ApplicationContext
最终关闭时,它将成为第一个被调用的方法。
<强>参考:强>
答案 1 :(得分:1)
我遇到过同样的问题。检查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 - &gt; LifeCycle - &gt;豆祸。
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's BeanFactory.
destroyBeans();
// Close the state of this context itself.
closeBeanFactory();
// Let subclasses do some final clean-up if they wish...
onClose();