【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);
		}
	}东方鲤鱼

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Spring 启动过程是一个比较复杂的过程,主要包括以下几个步骤: 1. 加载 Spring 配置文件,创建 Bean 的定义信息。 2. 根据 Bean 的定义信息创建 Bean 实例,并进行依赖注入。 3. 将 Bean 实例注册到 Spring 容器中。 4. 根据配置信息对 Bean 实例进行初始化。 5. 在 Spring 容器启动完成后,触发相关的回调方法。 其中,涉及到的主要源码方法如下: 1. 加载 Spring 配置文件,创建 Bean 的定义信息: - `org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinition`:注册 Bean 定义信息。 - `org.springframework.beans.factory.support.BeanDefinitionReaderUtils#registerBeanDefinition`:注册 Bean 定义信息的工具类方法。 2. 根据 Bean 的定义信息创建 Bean 实例,并进行依赖注入: - `org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean`:获取 Bean 实例的入口方法。 - `org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean`:创建 Bean 实例的方法。 - `org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean`:进行依赖注入的方法。 3. 将 Bean 实例注册到 Spring 容器中: - `org.springframework.beans.factory.support.AbstractBeanFactory#registerSingleton`:注册单例 Bean 实例的方法。 - `org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingleton`:添加单例 Bean 实例的方法。 4. 根据配置信息对 Bean 实例进行初始化: - `org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean`:对 Bean 实例进行初始化的方法。 5. 在 Spring 容器启动完成后,触发相关的回调方法: - `org.springframework.context.support.AbstractApplicationContext#refresh`:刷新 Spring 容器,触发回调方法的入口方法。 - `org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors`:执行 BeanFactoryPostProcessor方法。 - `org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization`:完成 BeanFactory 初始化的方法。 - `org.springframework.context.support.AbstractApplicationContext#finishRefresh`:完成 Spring 容器的刷新,触发相关回调方法方法

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东方鲤鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值