【spring】源码-spring 容器启动过程之finishRefresh()方法(十一)

目录

finishRefresh()

   initLifecycleProcessor()

  onRefresh()

contextDestroyed()


 

finishRefresh()

      protected void finishRefresh() {
		// Clear context-level resource caches (such as ASM metadata from scanning).
		clearResourceCaches();

		// Initialize lifecycle processor for this context.
		// 为应用上下文 初始化 LifecycleProcessor
		initLifecycleProcessor();

		// Propagate refresh to lifecycle processor first.
		getLifecycleProcessor().onRefresh();

		// Publish the final event.
		//推送上下文刷新完毕事件到相应的监听器
		publishEvent(new ContextRefreshedEvent(this));

		// Participate in LiveBeansView MBean, if active.
		LiveBeansView.registerApplicationContext(this);
	}

   initLifecycleProcessor()

protected void initLifecycleProcessor() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		//判断BeanFactory是否已经存在生命周期处理器(固定使用beanName=lifecycleProcessor
		if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
			this.lifecycleProcessor =
					beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
			if (logger.isDebugEnabled()) {
				logger.debug("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
			}
		}
		else {
			// 不存在就使用默认DefaultLifecycleProcessor
			DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
			defaultProcessor.setBeanFactory(beanFactory);
			this.lifecycleProcessor = defaultProcessor;
			// 把默认处理器注册到容器种
			beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
			if (logger.isDebugEnabled()) {
				logger.debug("Unable to locate LifecycleProcessor with name '" +
						LIFECYCLE_PROCESSOR_BEAN_NAME +
						"': using default [" + this.lifecycleProcessor + "]");
			}
		}
	}

  onRefresh()

    @Override
	public void onRefresh() {
		startBeans(true);
		this.running = true;
	}



	  private void startBeans(boolean autoStartupOnly) {
		// 返回所有实现了Lifecycle bean
		Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
		//key:如果实现了SmartLifeCycle,则为其getPhase方法返回的值,如果只是实现了Lifecycle,默认返回0
		 // value:相同phase的Lifecycle的集合,并将其封装到了一个LifecycleGroup中
		Map<Integer, LifecycleGroup> phases = new HashMap<>();
		lifecycleBeans.forEach((beanName, bean) -> {
			if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
				// 获得当前bean 的优先级
				int phase = getPhase(bean);
				//分组
				LifecycleGroup group = phases.get(phase);
				if (group == null) {
					group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
					phases.put(phase, group);
				}
				group.add(beanName, bean);
			}
		});
		if (!phases.isEmpty()) {
			List<Integer> keys = new ArrayList<>(phases.keySet());
			//排序
			Collections.sort(keys);
			for (Integer key : keys) {
				phases.get(key).start();
			}
		}
	}

解析:group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly) 参数解释:

                phase:代表这一组lifecycleBeans的执行阶段;
                timeoutPerShutdownPhase:因为lifecycleBean中的stop方法可以在另一个线程中运行,所以为了确保当前阶段的所有lifecycleBean都执行完,Spring使用了CountDownLatch,防止出现超时等待,所有这里设置了一个等待的最大时间,默认为30秒;
                lifecycleBeans:所有的实现了Lifecycle的Bean;
                autoStartupOnly: 手动调用容器的start方法时,为false。容器启动阶段自动调用时为true;

Lifecycle 接口 :任何Spring管理的对象都可以实现此接口。当ApplicationContext接口启动和关闭时,它会调用本容器内所有的Lifecycle实现

实现类有LifecycleProcessor与LifecycleProcessor;

LifecycleProcessor:增加了两个扩展实现发方法,LifecycleProcessor接口在Spring中的默认实现是DefaultLifecycleProcessor类,该类会为每个回调等待超时,默认超时是30秒。可以重写该类默认的参数,该类在容器内默认bean名称是lifecycleProcessor。比如修改超时时间

SmartLifecycle:又继承了Phased 类,SmartLifecycle中stop()方法有一个回调参数。所有的实现在关闭处理完成后会调用回调的run()方法,相当于开启异步关闭功能。

contextDestroyed()

当我们停止容器的时候会触发,释放资源;

/**
	 * 销毁根web应用程序上下文.
	 */
	@Override
	public void contextDestroyed(ServletContextEvent event) {
		closeWebApplicationContext(event.getServletContext());
		ContextCleanupListener.cleanupAttributes(event.getServletContext());
	}
closeWebApplicationContext(ServletContext servletContext) 方法用来将上下文置为空 ,同时把根容器也从上下文中移除;
public void closeWebApplicationContext(ServletContext servletContext) {
		servletContext.log("Closing Spring root WebApplicationContext");
		try {
			if (this.context instanceof ConfigurableWebApplicationContext) {
				((ConfigurableWebApplicationContext) this.context).close();
			}
		}
		finally {
			ClassLoader ccl = Thread.currentThread().getContextClassLoader();
			if (ccl == ContextLoader.class.getClassLoader()) {
				// 置空
				currentContext = null;
			}
			else if (ccl != null) {
				currentContextPerThread.remove(ccl);
			}
			// 移除根容器
			servletContext.removeAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
		}
	}东方鲤鱼

猜你喜欢

转载自blog.csdn.net/zy_jun/article/details/115347204
今日推荐