You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@dubbo.apache.org by "superleo-cn (GitHub)" <gi...@apache.org> on 2019/09/22 03:17:27 UTC
[GitHub] [dubbo] superleo-cn commented on issue #4288: dubbo2.7.1官网上优雅停机示例方法没有
先说结论:如果是和Spring集成那么这个不用担心2个冲突执行的问题,因为初始化的时候dubbo就从runtime改到spring context上去了:
源码追踪如下:
Dubbo源码 org.apache.dubbo.config.spring.extension.SpringExtensionFactory.java:
```java
public class SpringExtensionFactory implements ExtensionFactory {
private static final Logger logger = LoggerFactory.getLogger(SpringExtensionFactory.class);
private static final Set<ApplicationContext> CONTEXTS = new ConcurrentHashSet<ApplicationContext>();
private static final ApplicationListener SHUTDOWN_HOOK_LISTENER = new ShutdownHookListener();
public static void addApplicationContext(ApplicationContext context) {
CONTEXTS.add(context);
if (context instanceof ConfigurableApplicationContext) {
// 注册到spring上面
((ConfigurableApplicationContext) context).registerShutdownHook();
// 从java.lang.Runtime.getRuntime() 中取消注册
DubboShutdownHook.getDubboShutdownHook().unregister();
}
BeanFactoryUtils.addApplicationListener(context, SHUTDOWN_HOOK_LISTENER);
}
```
然后在 Spring接到kill信号的时候,进入hook回调,然后spring在依次去调用Application Event通知各个注册在spring hook的bean去执行他们自己的hook回调:
这个是dubbo和spring集成后的hook操作
```java
private static class ShutdownHookListener implements ApplicationListener {
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ContextClosedEvent) {
DubboShutdownHook shutdownHook = DubboShutdownHook.getDubboShutdownHook();
shutdownHook.doDestroy();
}
}
}
```
等到执行完成后,spring才去销毁对象。
Spring 源码 org.springframework.context.support.AbstractApplicationContext.java:
```java
protected void doClose() {
// Check whether an actual close attempt is necessary...
if (this.active.get() && this.closed.compareAndSet(false, true)) {
if (logger.isDebugEnabled()) {
logger.debug("Closing " + this);
}
LiveBeansView.unregisterApplicationContext(this);
try {
// 看这里,通知各个hook去关闭
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.
if (this.lifecycleProcessor != null) {
try {
this.lifecycleProcessor.onClose();
}
catch (Throwable ex) {
logger.warn("Exception thrown from LifecycleProcessor on context close", ex);
}
}
// 开始销毁单例对象等
destroyBeans();
// 销毁Bean工厂
closeBeanFactory();
// Let subclasses do some final clean-up if they wish...
onClose();
// Reset local application listeners to pre-refresh state.
if (this.earlyApplicationListeners != null) {
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// Switch to inactive.
this.active.set(false);
...
}
}
```
[ Full content available at: https://github.com/apache/dubbo/issues/4288 ]
This message was relayed via gitbox.apache.org for notifications@dubbo.apache.org