Spring IOC容器启动流程 AbstractApplicationContext#refresh()方法源码分析

refresh()方法是Spring容器启动的核心中的核心,逻辑也是异常的复杂,因为准备分两篇文章来叙述他的过程,以及源码的分析

Spring Bean声明周期流程图

Spring Bean的完整生命周期从创建Spring容器开始,直到最终Spring容器销毁Bean,这其中包含了一系列关键点。

Created with Raphaël 2.2.0 实例化BeanFactoryPostProcessor的实现类 执行BeanFactoryPostProcessor的postProcessBeanFactory方法 实例化BeanPostProcessor的实现类 实例化InstantiationAwareBeanPostProcessorAdapter的实现类 执行InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法 执行Bean的构造器 执行InstantiationAwareBeanPostProcessor的postProcessPropertyValues方法 为Bean注入属性 调用BeanNameAware的setBeanName方法 调用BeanFactoryAware的setBeanFactory方法 执行BeanPostProcessor的postProcessBeforeInitialization方法 执行InitializingBean的afterPropertiesSet方法 调用<bean>的init-method属性指定的方法 执行BeanPostProcessor的postProcessAfterInitialization方法 执行InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation方法 容器初始化完成,执行正常调用后,下面销毁容器 执行DisposableBean的destroy方法 调用<bean>的destory-method属性指定的方法

简单分类如下:

  • 工厂后置处理器(BeanFactoryPostProcessor):这个包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等非常有用的工厂后处理器  接口的方法。工厂后处理器也是容器级的。
  • 容器级别生命周期处理器:包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”
  • Bean级生命周期接口方法(仅作用于某个Bean):这个包括了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这些接口的方法
  • Bean自身的方法:这个包括了Bean本身调用的方法和通过配置文件中<bean>的init-method和destroy-method指定的方法

因为我们项目的案例是全注解驱动的,因此我们的容器实例为:AnnotationConfigWebApplicationContext(若你是xml配置驱动,则为XmlWebApplicationContext)

refresh()方法所有的ApplicationContext子类都没重写,只有AbstractApplicationContext里有实现过(接口定义在ConfigurableApplicationContext)

AbstractApplicationContext#refresh()

	@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			//容器刷新前的准备,设置上下文状态,获取属性,验证必要的属性等
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			// 获取新的beanFactory,销毁原有beanFactory、为每个bean生成BeanDefinition等  
			// 注意,此处是获取新的,销毁旧的,这就是刷新的意义
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			//配置标准的beanFactory,设置ClassLoader,设置SpEL表达式解析器等
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				//模板方法,允许在子类中对beanFactory进行后置处理。
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				//实例化并调用所有注册的beanFactory后置处理器(实现接口BeanFactoryPostProcessor的bean)。
				//在beanFactory标准初始化之后执行  例如:PropertyPlaceholderConfigurer(处理占位符)
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				//实例化和注册beanFactory中扩展了BeanPostProcessor的bean。
				//例如:
				//AutowiredAnnotationBeanPostProcessor(处理被@Autowired注解修饰的bean并注入)
				//RequiredAnnotationBeanPostProcessor(处理被@Required注解修饰的方法)
				//CommonAnnotationBeanPostProcessor(处理@PreDestroy、@PostConstruct、@Resource等多个注解的作用)等。
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				//初始化国际化工具类MessageSource
				initMessageSource();

				// Initialize event multicaster for this context.
				//初始化事件广播器
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				//模板方法,在容器刷新的时候可以自定义逻辑(子类自己去实现逻辑),不同的Spring容器做不同的事情
				onRefresh();

				// Check for listener beans and register them.
				//注册监听器,并且广播early application events,也就是早期的事件
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				//非常重要。。。实例化所有剩余的(非懒加载)单例Bean。(也就是我们自己定义的那些Bean们)
				//比如invokeBeanFactoryPostProcessors方法中根据各种注解解析出来的类,在这个时候都会被初始化  扫描的 @Bean之类的
				//实例化的过程各种BeanPostProcessor开始起作用
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				//refresh做完之后需要做的其他事情
				//清除上下文资源缓存(如扫描中的ASM元数据)
				//初始化上下文的生命周期处理器,并刷新(找出Spring容器中实现了Lifecycle接口的bean并执行start()方法)。
				//发布ContextRefreshedEvent事件告知对应的ApplicationListener进行响应的操作
				finishRefresh();
			} catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				//如果刷新失败那么就会将已经创建好的单例Bean销毁掉
				destroyBeans();

				// Reset 'active' flag.
				//重置context的活动状态 告知是失败的
				cancelRefresh(ex);

				// Propagate exception to caller.
				//抛出异常
				throw ex;
			} finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				// 失败与否,都会重置Spring内核的缓存。因为可能不再需要metadata给单例Bean了。
				resetCommonCaches();
			}
		}
	}

AbstractApplicationContext#prepareRefresh()

	protected void prepareRefresh() {
		//记录容器启动时间,然后设立对应的标志位
		this.startupDate = System.currentTimeMillis();
		this.closed.set(false);
		this.active.set(true);

		// 打印info日志:开始刷新this此容器了
		if (logger.isInfoEnabled()) {
			logger.info("Refreshing " + this);
		}

		// Initialize any placeholder property sources in the context environment
		// 这是扩展方法,由子类去实现,可以在验证之前为系统属性设置一些值可以在子类中实现此方法
		// 因为我们这边是AnnotationConfigApplicationContext,可以看到不管父类还是自己,都什么都没做,所以此处先忽略
		initPropertySources();

		// Validate that all properties marked as required are resolvable
		// see ConfigurablePropertyResolver#setRequiredProperties
		//这里有两步,getEnvironment(),然后是是验证是否系统环境中有RequiredProperties参数值 如下详情
		// 然后管理Environment#validateRequiredProperties 后面在讲到环境的时候再专门讲解吧
		// 这里其实就干了一件事,验证是否存在需要的属性
		getEnvironment().validateRequiredProperties();

		// Allow for the collection of early ApplicationEvents,
		// to be published once the multicaster is available...
		// 初始化容器,用于装载早期的一些事件
		this.earlyApplicationEvents = new LinkedHashSet<>();
	}

AbstractApplicationContext#getEnvironment()

实现了接口EnvironmentCapable的getEnvironment()方法

	@Override
	public ConfigurableEnvironment getEnvironment() {
		if (this.environment == null) {
			this.environment = createEnvironment();
		}
		return this.environment;
	}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值