在我在Tomcat中运行的webapp中,我有两个实现SmartLifecycle
的Spring 5.0.2类。他们按预期开始,但不要停止。我在日志文件中看到以下内容:
INFO o.s.c.s.DefaultLifecycleProcessor$LifecycleGroup [localhost-startStop-2] Stopping beans in phase 2147483647
DEBUG o.s.c.s.DefaultLifecycleProcessor [localhost-startStop-2] Asking bean 'myQueue1' of type ... to stop
DEBUG o.s.c.s.DefaultLifecycleProcessor [localhost-startStop-2] Asking bean 'myQueue2' of type ... to stop
WARN o.s.c.s.DefaultLifecycleProcessor$LifecycleGroup [localhost-startStop-2] Failed to shut down 2 beans with phase value 2147483647 within timeout of 30000: [myQueue1, myQueue2]
我在调试器中运行Java进程,并且我没有点击stop()
方法中第一行的断点(另一次写入日志)。
以下是我实现的与停止相关的SmartLifeCycle
方法(两个类都相同)。为什么stop
没有被执行?任何调试技巧也欢迎。
@Component
@Scope(value = "singleton")
public class MyQueue1 implements SmartLifecycle
{
@Override
public void stop(Runnable runnable) {
}
@Override
public void stop() {
logger.info("Stop for " + queueName);
}
@Override
public boolean isRunning() {
return queueThread != null;
}
@Override
public int getPhase() {
return Integer.MAX_VALUE; // Suggest last to start; first to stop
}
}
答案 0 :(得分:2)
Spring会保持一个倒数计时,以确保所有“停止”方法均已完成。这是DefaultLifeCycleProcessor.java中的代码片段
((SmartLifecycle)bean).stop(new Runnable() {
public void run() {
latch.countDown();
countDownBeanNames.remove(beanName);
if(DefaultLifecycleProcessor.this.logger.isDebugEnabled()) {
DefaultLifecycleProcessor.this.logger.debug("Bean '" + beanName + "' completed its stop procedure");
}
}
});
因此,在您的代码中,因为您没有在传递的runnable中调用此“ run”方法,并且由于在DefaultLifecycleProcessor.java中的以下代码段执行以下代码时,锁存器的倒计时值大于0。因此,您获得了“失败。”警告日志。
try {
latch.await(this.timeout, TimeUnit.MILLISECONDS);
if(latch.getCount() > 0L && !countDownBeanNames.isEmpty() && DefaultLifecycleProcessor.this.logger.isWarnEnabled()) {
DefaultLifecycleProcessor.this.logger.warn("Failed to shut down " + countDownBeanNames.size() + " bean" + (countDownBeanNames.size() > 1?"s":"") + " with phase value " + this.phase + " within timeout of " + this.timeout + ": " + countDownBeanNames);
}
} catch (InterruptedException var5) {
Thread.currentThread().interrupt();
}
现在,要解决此问题,请在stop(Runnable runnable)方法中调用以下方法。
runnable.run();
答案 1 :(得分:0)
您的依赖关系可能会影响生命周期。
从Spring文档:
任何明确的“依赖”关系都优先于 阶段顺序,以便依赖bean始终在其之后启动 依赖关系并始终在其依赖之前停止。