首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么SmartLifecycle组件不关闭?

为什么SmartLifecycle组件不关闭?
EN

Stack Overflow用户
提问于 2018-03-06 16:47:00
回答 2查看 1.5K关注 0票数 2

在我运行在Tomcat中的webapp中,有两个Spring5.0.2类实现了SmartLifecycle。他们像预期的一样开始,但不要停止。我在日志文件中看到了以下内容:

代码语言:javascript
复制
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没有被执行?任何调试提示也欢迎。

代码语言:javascript
复制
@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
}

}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-07-20 11:36:09

Spring维护一个锁存倒计时,以确保所有“停止”方法都已完成。以下是来自DefaultLifeCycleProcessor.java的代码

代码语言:javascript
复制
((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。因此,你会得到“失败..”警告日志。

代码语言:javascript
复制
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()方法中解决以下方法中的问题调用。

代码语言:javascript
复制
runnable.run();
票数 3
EN

Stack Overflow用户

发布于 2018-03-06 17:27:56

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

来自Spring文档:

任何显式的“依赖”关系都将优先于阶段顺序,因此依赖bean总是在依赖关系之后开始,并且总是在依赖关系之前停止。

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/SmartLifecycle.html

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49135989

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档