1. 程式人生 > >Springboot內建ApplicationListener--ParentContextCloserApplicationListener

Springboot內建ApplicationListener--ParentContextCloserApplicationListener

原始碼分析

本文原始碼基於 Springboot 2.1.0


package org.springframework.boot.builder;

import java.lang.ref.WeakReference;

import org.springframework.beans.BeansException;
import org.springframework.boot.builder.ParentContextApplicationContextInitializer.
	ParentContextAvailableEvent;
import org.
springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationListener; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.event.ContextClosedEvent; import org.springframework.
core.Ordered; import org.springframework.util.ObjectUtils; /** * Listener that closes the application context if its parent is closed. It listens for * refresh events and grabs the current context from there, and then listens for closed * events and propagates it down the hierarchy. * * 在一個應用上下文的雙親應用上下文關閉時關閉該應用上下文。這個監聽器監聽應用上下文重新整理事件並從中取出 * 應用上下文,然後監聽關閉事件在應用上下文的層級結構中往下層傳播該事件。 * * @author Dave Syer * @author Eric Bottard */
public class ParentContextCloserApplicationListener implements ApplicationListener<ParentContextAvailableEvent>, ApplicationContextAware, Ordered { private int order = Ordered.LOWEST_PRECEDENCE - 10; private ApplicationContext context; @Override public int getOrder() { return this.order; } @Override public void setApplicationContext(ApplicationContext context) throws BeansException { this.context = context; } // 當一個應用上下文中發出ParentContextAvailableEvent 事件時,表明該應用上下文被設定了雙親 // 應用上下文並且自己已經可用(refreshed),現在在該應用上下文的雙親上下文中登記一個事件監聽器, // 用於監聽雙親上下文的關閉事件,從而關閉該子應用上下文。 @Override public void onApplicationEvent(ParentContextAvailableEvent event) { maybeInstallListenerInParent(event.getApplicationContext()); } private void maybeInstallListenerInParent(ConfigurableApplicationContext child) { if (child == this.context && child.getParent() instanceof ConfigurableApplicationContext) { ConfigurableApplicationContext parent = (ConfigurableApplicationContext) child .getParent(); parent.addApplicationListener(createContextCloserListener(child)); } } /** * Subclasses may override to create their own subclass of ContextCloserListener. This * still enforces the use of a weak reference. * @param child the child context * @return the {@link ContextCloserListener} to use */ protected ContextCloserListener createContextCloserListener( ConfigurableApplicationContext child) { return new ContextCloserListener(child); } /** * ApplicationListener to close the context. * * 定義一個應用事件監聽器,關注事件ContextClosedEvent,當該事件發生時,關閉指定的孩子應用上下文。 * 對於指定的孩子應用上下文使用WeakReference弱引用保持。 * 事件ContextClosedEvent發生時,如果弱引用中保持的孩子應用上下文還在(意思就是弱引用尚未釋放), * 並且孩子上下文處於活躍狀態,則關閉它。 * 注意 : 在關閉之前會再次檢查當前上下文和孩子上下文之間的父子關係,僅在父子關係成立的情況下才真正 * 做相應的關閉動作。 * * 該靜態內部類僅被ParentContextCloserApplicationListener用於向雙親應用上下文登記一個關閉孩子 * 引用上下文的ApplicationListener */ protected static class ContextCloserListener implements ApplicationListener<ContextClosedEvent> { private WeakReference<ConfigurableApplicationContext> childContext; public ContextCloserListener(ConfigurableApplicationContext childContext) { this.childContext = new WeakReference<>(childContext); } @Override public void onApplicationEvent(ContextClosedEvent event) { ConfigurableApplicationContext context = this.childContext.get(); if ((context != null) && (event.getApplicationContext() == context.getParent()) && context.isActive()) { context.close(); } } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (obj instanceof ContextCloserListener) { ContextCloserListener other = (ContextCloserListener) obj; return ObjectUtils.nullSafeEquals(this.childContext.get(), other.childContext.get()); } return super.equals(obj); } @Override public int hashCode() { return ObjectUtils.nullSafeHashCode(this.childContext.get()); } } }

相關文章

Springboot內建ApplicationListener