Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/apache/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring 为什么SmartLifecycle组件没有关闭?_Spring_Shutdown - Fatal编程技术网

Spring 为什么SmartLifecycle组件没有关闭?

Spring 为什么SmartLifecycle组件没有关闭?,spring,shutdown,Spring,Shutdown,在运行于Tomcat的webapp中,我有两个Spring 5.0.2类,它们实现了SmartLifecycle。它们按预期开始,但不会停止。我在日志文件中看到以下内容: INFO o.s.c.s.DefaultLifecycleProcessor$LifecycleGroup [localhost-startStop-2] Stopping beans in phase 2147483647 DEBUG o.s.c.s.DefaultLifecycleProcessor [localhost-

在运行于Tomcat的webapp中,我有两个Spring 5.0.2类,它们实现了
SmartLifecycle
。它们按预期开始,但不会停止。我在日志文件中看到以下内容:

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
方法(两个类的方法相同)。为什么不执行
停止
?也欢迎提供任何调试提示

@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
}

}

您的依赖关系可能会影响生命周期

从Spring文档中:

任何明确的“依赖”关系将优先于 相序,使得依赖bean总是在其 并且始终在其依赖项之前停止


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。因此,您将获得“failed..”警告日志

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)方法中调用下面的方法


好了,没有依赖关系。我将调试放大到“跟踪”,以查看是否可以在30秒的超时窗口中看到关闭其他bean的尝试,但什么都没有。
runnable.run();