Spring 5 ApplicationContext#refresh() --finishRefresh 源码解析

相关源码注释

ApplicationContext

Spring 5 DefaultResourceLoader 源码注释
Spring 5 AbstractApplicationContext 源码注释

BeanFactory

Spring 5 SimpleAliasRegistry 源码注释
Spring 5 DefaultSingletonBeanRegistry 源码注释
Spring 5 FactoryBeanRegistrySupport 源码注释
Spring 5 AbstractBeanFactory 源码注释
Spring 5 AbstractAutowireCapableBeanFactory 源码注释
Spring 5 DefaultLisbaleBeanFactory 源码注释

finishRefresh()

/**
	 * <p>完成刷新
	 * Finish the refresh of this context, invoking the LifecycleProcessor's
	 * onRefresh() method and publishing the
	 * {@link org.springframework.context.event.ContextRefreshedEvent}.
	 * <p>调用 LifecycleProcessor 的 onRefresh() 方法并发布 ContextRefreshedEvent ,完成上下
	 * 问刷新</p>
	 */
	protected void finishRefresh() {
    
    
		// Clear context-level resource caches (such as ASM metadata from scanning).
		// 清楚上下文级别的资源缓存(如扫描的ASM元数据)
		// 清空在资源加载器中的所有资源缓存
		clearResourceCaches();

		// Initialize lifecycle processor for this context.
		// 为这个上下文初始化生命周期处理器
		// 初始化 LifecycleProcessor.如果上下文中找到 'lifecycleProcessor' 的 LifecycleProcessor Bean对象,
		// 		则使用 DefaultLifecycleProcessor
		initLifecycleProcessor();

		// Propagate refresh to lifecycle processor first.
		// 首先将刷新传播到生命周期处理器
		// 上下文刷新的通知,例如自动启动的组件
		getLifecycleProcessor().onRefresh();

		// Publish the final event.
		// 发布最终事件
		// 新建 ContextRefreshedEvent 事件对象,将其发布到所有监听器。
		publishEvent(new ContextRefreshedEvent(this));

		// Participate in LiveBeansView MBean, if active.
		// 参与 LiveBeansView MBean,如果是活动的
		// LiveBeansView:Sping 用于支持 JMX 服务的类,详情请参考:https://www.jianshu.com/p/fa4e88f95631
		// 注册 当前上下文 到 LiveBeansView,以支持 JMX 服务
		LiveBeansView.registerApplicationContext(this);
	}

完成刷新:

  1. 清空在资源加载器中的所有资源缓存
  2. 初始化 LifecycleProcessor.如果上下文中找到 ‘lifecycleProcessor’ 的 LifecycleProcessor Bean对象, 则使用 DefaultLifecycleProcessor
  3. 将刷新传播到生命周期处理器
  4. 新建 ContextRefreshedEvent 事件对象,将其发布到所有监听器。
  5. 注册 当前上下文 到 LiveBeansView,以支持 JMX 服务

clearResourceCaches();

	/**
	 * 资源映射缓存
	 */
	private final Map<Class<?>, Map<Resource, ?>> resourceCaches = new ConcurrentHashMap<>(4);
/**
	 * Clear all resource caches in this resource loader.
	 * <p>
	 *     清空在资源加载器中的所有资源缓存
	 * </p>
	 * @since 5.0
	 * @see #getResourceCache
	 */
	public void clearResourceCaches() {
    
    
		//清空resourceCaches
		this.resourceCaches.clear();
	}

initLifecycleProcessor()

	/**
	 * <p><p>初始化 LifecycleProcessor.如果上下文中找到 'lifecycleProcessor' 的 LifecycleProcessor Bean对象,则使用
	 * 	DefaultLifecycleProcessor </p></p>
	 * Initialize the LifecycleProcessor.
	 * Uses DefaultLifecycleProcessor if none defined in the context.
	 * <p>初始化 LifecycleProcessor.如果上下文中没有定义,则使用 DefaultLifecycleProcessor </p>
	 * @see org.springframework.context.support.DefaultLifecycleProcessor
	 */
	protected void initLifecycleProcessor() {
    
    
		//获取当前上下文的BeanFactory对象
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		//如果 beanFactory 包含 'lifecycleProcessor' 的bean,忽略父工厂
		if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
    
    
			//让当前上下文 引用 从beanFactory中获取名为 'lifecycleProcessor' 的 LifecycleProcessor 类型的Bean对象
			this.lifecycleProcessor =
					beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
			//如果当前日志级级别是跟踪
			if (logger.isTraceEnabled()) {
    
    
				//打印跟踪日志:使用 LifecycleProcessor [lifecycleProcessor]
				logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
			}
		}
		else {
    
    
			//创建一个 DefaultLifecycleProcessor 实例
			DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
			//为Bean实例提供所属工厂的回调函数
			defaultProcessor.setBeanFactory(beanFactory);
			//让当前上下文 引用 defaultProcessor
			this.lifecycleProcessor = defaultProcessor;
			//将 'lifecycleProcessor' 与 lifecycleProcessor 注册到 beanFactory 中
			beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
			//如果当前日志级级别是跟踪
			if (logger.isTraceEnabled()) {
    
    
				// 没有 'lifecycleProcessor' 的Bean对象,使用 [lifecycleProcessor类名]
				logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " +
						"[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");
			}
		}
	}

Spring 5 DefaultLifecycleProcessor 源码分析

publishEvent(new ContextRefreshedEvent(this));

/**
	 * Publish the given event to all listeners.
	 * <p>将给定事件发布到所有监听器。</p>
	 * <p>Note: Listeners get initialized after the MessageSource, to be able
	 * to access it within listener implementations. Thus, MessageSource
	 * implementations cannot publish events.
	 * <p>注意:侦听器在MessageSource之后被初始化,以便能够在侦听器实现中访问它。
	 * 因此,MessageSource实现不能发布事件</p>
	 * @param event the event to publish (may be application-specific or a
	 * standard framework event)
	 *              -- 要发布的事件(可能是特定于应用程序的事件或标准框架事件)
	 */
	@Override
	public void publishEvent(ApplicationEvent event) {
    
    
		publishEvent(event, null);
	}

	/**
	 * Publish the given event to all listeners.
	 * <p>将给定事件发布到所有监听器。</p>
	 * <p>Note: Listeners get initialized after the MessageSource, to be able
	 * to access it within listener implementations. Thus, MessageSource
	 * implementations cannot publish events.
	 * <p>注意:侦听器在MessageSource之后被初始化,以便能够在侦听器实现中访问它。 因此,MessageSource实现不能发布事件</p>
	 * @param event the event to publish (may be an {@link ApplicationEvent}
	 * or a payload object to be turned into a {@link PayloadApplicationEvent})
	 *              -- 要发布的事件(可能是特定于应用程序的事件或标准框架事件)
	 */
	@Override
	public void publishEvent(Object event) {
    
    
		publishEvent(event, null);
	}

	/**
	 * <p>将 event 多播到所有适合的监听器。如果 event 不是 ApplicationEvent 实例,会将其封装成 PayloadApplicationEvent 对象
	 * 	再进行多播。</p>
	 * <p>当上下文的多播器没有初始化时,会将event暂时保存起来,待多播器初始化后才将缓存的event进行多播</p>
	 * Publish the given event to all listeners.
	 * <p>将给定事件发布到所有监听器</p>
	 * @param event the event to publish (may be an {@link ApplicationEvent}
	 * or a payload object to be turned into a {@link PayloadApplicationEvent})
	 *    -- 要发布的事件(可能是特定于应用程序的事件或标准框架事件)
	 * @param eventType the resolved event type, if known -- 已解析的事件类型(如果已知)
	 * @since 4.2
	 */
	protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
    
    
		//如果 event 为null,抛出异常
		Assert.notNull(event, "Event must not be null");

		// Decorate event as an ApplicationEvent if necessary
		// 装饰事件作为一个应用事件,如果有必要
		ApplicationEvent applicationEvent;
		//如果 event 是 ApplicationEvent 的 实例
		if (event instanceof ApplicationEvent) {
    
    
			//将 event 强转为 ApplicationEvent 对象
			applicationEvent = (ApplicationEvent) event;
		}
		else {
    
    
			//PayloadApplicationEvent:携带任意有效负载的ApplicationEvent。
			//创建一个新的 PayloadApplicationEvent
			applicationEvent = new PayloadApplicationEvent<>(this, event);
			//如果 eventType 为 null
			if (eventType == null) {
    
    
				//将 applicationEvent 转换为 PayloadApplicationEvent 对象,引用其 ResolvableType 对象
				eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
			}
		}

		// Multicast right now if possible - or lazily once the multicaster is initialized
		// 如果可能的话,现在就进行组播——或者在组播初始化后延迟
		// earlyApplicationEvents:在多播程序设置之前发布的ApplicationEvent
		// 如果 earlyApplicationEvents 不为 null,这种情况只在上下文的多播器还没有初始化的情况下才会成立, 会将 applicationEvent
		// 		添加到 earlyApplicationEvents 保存起来,待多博器初始化后才继续进行多播到适当的监听器
		if (this.earlyApplicationEvents != null) {
    
    
			//将applicationEvent添加到 earlyApplicationEvents
			this.earlyApplicationEvents.add(applicationEvent);
		}
		else {
    
    
			//多播applicationEvent到适当的监听器
			getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
		}

		// Publish event via parent context as well...
		// 通过父上下文发布事件
		// 如果 parent 不为 null
		if (this.parent != null) {
    
    
			//如果 parent 是 AbstractApplicationContext 的实例
			if (this.parent instanceof AbstractApplicationContext) {
    
    
				//将 event 多播到所有适合的监听器。如果 event 不是 ApplicationEvent 实例,会将其封装成 PayloadApplicationEvent 对象再进行多播
				((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
			}
			else {
    
    
				//通知与event事件应用程序注册的所有匹配的监听器
				this.parent.publishEvent(event);
			}
		}
	}

LiveBeansView.registerApplicationContext(this);

/**
	 * The "MBean Domain" property name.
	 * <p>'MBean Domain' 属性名</p>
	 */
	public static final String MBEAN_DOMAIN_PROPERTY_NAME = "spring.liveBeansView.mbeanDomain";

	/**
	 * The MBean application key.
	 * <p> MBean 应用 Key</p>
	 */
	public static final String MBEAN_APPLICATION_KEY = "application";

	/**
	 * applicationContext 集
	 */
	private static final Set<ConfigurableApplicationContext> applicationContexts = new LinkedHashSet<>();

	/**
	 * 此上下文所属的已部署应用程序的名称
	 */
	@Nullable
	private static String applicationName;


	/**
	 * 注册 applicationContext
	 * @param applicationContext 应用程序上下文
	 */
	static void registerApplicationContext(ConfigurableApplicationContext applicationContext) {
    
    
		//从 applicationContext 中环境对象中获取 'spring.liveBeansView.mbeanDomain' 的属性值
		String mbeanDomain = applicationContext.getEnvironment().getProperty(MBEAN_DOMAIN_PROPERTY_NAME);
		//如果 mbeanDomain 不为 null
		if (mbeanDomain != null) {
    
    
			//使用 applicationContexts 进行同步加锁,保证线程安全
			synchronized (applicationContexts) {
    
    
				//如果 applicationContexts 是空集合
				if (applicationContexts.isEmpty()) {
    
    
					try {
    
    
						//ManagementFactory.getPlatformMBeanServer()返回对JVM中现有MBean服务器的引用
						//MBean 即 managed beans【被管理的Beans】:一个MBean是一个被管理的Java对象,有点类似于JavaBean,
						// 一个设备、一个应用或者任何资源都可以被表示为MBean,MBean会暴露一个接口对外,这个接口可以读取
						// 或者写入一些对象中的属性,通常一个MBean需要定义一个接口,以MBean结尾, 例如: EchoMBean,
						// 格式为XXXMBean,这个是规范,必须得遵守。
						MBeanServer server = ManagementFactory.getPlatformMBeanServer();
						//获取此上下文所属的已部署应用程序的名称
						applicationName = applicationContext.getApplicationName();
						//在MBeanServer里注册MBean, 标识为 mbeanDomain:application=applicationName
						server.registerMBean(new LiveBeansView(),
								new ObjectName(mbeanDomain, MBEAN_APPLICATION_KEY, applicationName));
					}
					catch (Throwable ex) {
    
    //捕捉注册时抛出的异常
						//抛出应用程序上下文异常:注册 LiveBeansView MBean 失败
						throw new ApplicationContextException("Failed to register LiveBeansView MBean", ex);
					}
				}
				//将 applicationContext 添加到 applicationContexts中
				applicationContexts.add(applicationContext);
			}
		}
	}

猜你喜欢

转载自blog.csdn.net/qq_30321211/article/details/108326723
今日推荐