Spring源码-IOC容器初始化过程【2】

实验环境:spring-framework-5.0.2、jdk8、gradle4.3.1

 

容器的初始化过程主要通过AbstractApplicationContext的refresh()方法来完成,其主要步骤如下

AbstractApplicationContext#refresh()方法

refresh方法
/**
	 * refresh方法的主要作用是:在创建IoC容器前,如果已经有容器存在,需要把已有的容器销毁和关闭,
	 * 以保证在refresh方法之后使用的是新创建的IoC容器。
	 * 它类似于对IoC容器的重启,在新创建的容器中对容器进行初始化,对Bean配置资源进行载入。
	 */
	@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// 1、准备刷新,获取当前时间,给容器设置同步表识
			prepareRefresh();

			// 2、子类刷新并初始化BeanFactory,在这一步生成beanFactory实例(DefaultListableBeanFactory),
			// 在这里完成BeanDefinition的加载(loadBeanDefinitions)
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// 3、初始化beanFactory,设置容器特性,例如类加载器、事件处理器等
			prepareBeanFactory(beanFactory);

			try {
				// 4、空方法,bean实例化之前执行。容器子类可以对beanFactory做一些操作
				postProcessBeanFactory(beanFactory);

				// 5、bean实例化之前执行。用户可以继承BeanFactoryPostProcessors接口,在这一步对beanFactory做一些操作
				invokeBeanFactoryPostProcessors(beanFactory);

				// 6、BeanPostProcessors是bean的后置处理器,用于监听容器触发的事件。
				// 在bean实例化之后,init-method方法前后执行
				// 用户可以继承BeanPostProcessors接口,在这一步对bean方法进行修改,具体执行在step12之后,这一步只是先注册上
				registerBeanPostProcessors(beanFactory);

				// 7、初始化信息源,和国际化相关
				initMessageSource();

				// 8、初始化事件传播器
				initApplicationEventMulticaster();

				// 9、空方法,容器子类可以在这一步进行操作
				onRefresh();

				// 10、为事件传播器,注册事件监听器
				registerListeners();

				// 11、【重要】实例化所有剩余的非懒加载单例bean,在这一步完成bean的实例化
				finishBeanFactoryInitialization(beanFactory);

				// 12、初始化容器的生命周期事件处理器,并且发布容器的生命周期事件
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// 销毁bean
				destroyBeans();

				// 取消刷新,重置active标示
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// 清空缓存
				resetCommonCaches();
			}
		}
	}

 

1、prepareRefresh方法

prepareRefresh方法
/**
	 * 准备刷新上下文,设置启动日期和活动标志、属性源的初始化。
	 */
	protected void prepareRefresh() {
		// 设置启动时间
		this.startupDate = System.currentTimeMillis();
		this.closed.set(false);
		this.active.set(true);

		if (logger.isInfoEnabled()) {
			logger.info("Refreshing " + this);
		}

		// 初始化上下文环境中的任何占位符属性源(空方法,交给子类实现)
		initPropertySources();

		// 创建并获取环境对象,验证所有标记为必需的属性是否可解析
		// 参考 ConfigurablePropertyResolver#setRequiredProperties
		getEnvironment().validateRequiredProperties();

		// 初始化earlyApplicationEvents,在multicaster可用后发布
		this.earlyApplicationEvents = new LinkedHashSet<>();
	}

 

2、obtainFreshBeanFactory方法:在这一步创建了beanFactory实例,并且进行了bean资源的加载

obtainFreshBeanFactory方法
/**
	 * 初始化BeanFactory,在这一步完成了loadBeanDefinitions的加载
	 */
	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		// 抽象方法,交给子类实现。
		// 子类刷新beanFactory,比如子类AbstractRefreshableApplicationContext会在refreshBeanFactory方法里createBeanFactory,并且执行loadBeanDefinitions加载资源配置。
		// 而GenericApplicationContext只会对已经创建好的beanFactory实例设置一下id即可,loadBeanDefinitions放在了外部去做。
		refreshBeanFactory();

		// getBeanFactory也是抽象方法,由子类创建beanFactory
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (logger.isDebugEnabled()) {
			logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
		}
		return beanFactory;
	}

 

比如子类AbstractRefreshableApplicationContext对其实现的refreshBeanFactory、getBeanFactory方法如下

refreshBeanFactory方法
/**
	 * 刷新BeanFactory,实现父类AbstractApplicationContext的抽象方法
	 */
	@Override
	protected final void refreshBeanFactory() throws BeansException {
		// 如果已经存在BeanFactory,销毁容器里的bean,关闭BeanFactory
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
			// 创建beanFactory
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			beanFactory.setSerializationId(getId());

			// 对IOC容器进行定制化,如设置启动参数、开启注解对自动装配等
			customizeBeanFactory(beanFactory);

			// 调用载入bean定义对方法,loadBeanDefinitions(beanFactory)在本类是个抽象方法,交给子类实现
			loadBeanDefinitions(beanFactory);

			// 加锁,写的时候不允许读写
			synchronized (this.beanFactoryMonitor) {
				this.beanFactory = beanFactory;
			}
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}

    protected DefaultListableBeanFactory createBeanFactory() {
		return new DefaultListableBeanFactory(getInternalParentBeanFactory());
	}

    @Override
	public final ConfigurableListableBeanFactory getBeanFactory() {
		// 加锁,读的时候不允许写
		synchronized (this.beanFactoryMonitor) {
			if (this.beanFactory == null) {
				throw new IllegalStateException("BeanFactory not initialized or already closed - " +
						"call 'refresh' before accessing beans via the ApplicationContext");
			}
			return this.beanFactory;
		}
	}

 

3、prepareBeanFactory方法:对beanFactory做一些初始化的工作,设置一些默认属性

prepareBeanFactory方法
/**
	 * 为BeanFactory设置一些初始化的属性值,例如上下文的类加载器和后处理器。
	 */
	protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// Tell the internal bean factory to use the context's class loader etc.
		beanFactory.setBeanClassLoader(getClassLoader());
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// Configure the bean factory with context callbacks.
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

		// 设置忽略的Aware接口
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
		beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

		// BeanFactory interface not registered as resolvable type in a plain factory.
		// MessageSource registered (and found for autowiring) as a bean.
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		// Register early post-processor for detecting inner beans as ApplicationListeners.
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

		// Detect a LoadTimeWeaver and prepare for weaving, if found.
		if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			// Set a temporary ClassLoader for type matching.
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}

		// Register default environment beans.
		if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
		}
	}

 

4、postProcessBeanFactory方法

查看代码
/**
	 * 根据上下文的标准修改其内部bean工厂初始化。所有bean定义都已加载,但没有bean将被实例化。
	 * 这允许注册特殊的BeanPostProcessors等在某些ApplicationContext实现中。
	 */
	protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	}

比如子类AbstractRefreshableWebApplicationContext对其实现如下

查看代码
/**
	 * 注册request/session作用域
	 */
	@Override
	protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// 添加Servlet容器相关的后置处理器
		beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
		beanFactory.ignoreDependencyInterface(ServletContextAware.class);
		beanFactory.ignoreDependencyInterface(ServletConfigAware.class);

		WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
		WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
	}

 

5、invokeBeanFactoryPostProcessors方法:在这一步对BeanDefinition进行增强(相关修改操作)

invokeBeanFactoryPostProcessors方法
/**
	 * BeanFactoryPostProcessor是在spring容器加载了beanDefinition之后,在bean实例化之前执行的。
	 * 实现BeanFactoryPostProcessor接口,可以在bean实例化之前修改beanDefinition相关配置。
	 * 可以同时配置多个BeanFactoryPostProcessor,并通过设置'order'属性来控制各个BeanFactoryPostProcessor的执行次序。
	 */
	protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

		// 检测LoadTimeWeaver并准备编织(如果同时发现)(例如,通过ConfigurationClassPostProcessor注册的@Bean方法)
		if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
	}

 

6、registerBeanPostProcessors方法

查看代码

/**
	 * BeanPostProcessor,可以在spring容器实例化bean之后,在执行bean的初始化方法前后,添加一些自己的处理逻辑。
	 */
	protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
	}

 

7、initMessageSource方法

查看代码
/**
	 * Initialize the MessageSource.
	 * Use parent's if none defined in this context.
	 */
	protected void initMessageSource() {
		// 这里获取的beanFactory和refresh里obtainFreshBeanFactory获取的是同一个,
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();

		if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
			this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
			// Make MessageSource aware of parent MessageSource.
			if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
				HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
				if (hms.getParentMessageSource() == null) {
					// Only set parent context as parent MessageSource if no parent MessageSource
					// registered already.
					hms.setParentMessageSource(getInternalParentMessageSource());
				}
			}
			if (logger.isDebugEnabled()) {
				logger.debug("Using MessageSource [" + this.messageSource + "]");
			}
		}
		else {
			// Use empty MessageSource to be able to accept getMessage calls.
			DelegatingMessageSource dms = new DelegatingMessageSource();
			dms.setParentMessageSource(getInternalParentMessageSource());
			this.messageSource = dms;
			beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
			if (logger.isDebugEnabled()) {
				logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +
						"': using default [" + this.messageSource + "]");
			}
		}
	}

 

8、initApplicationEventMulticaster方法

查看代码
/**
	 * spring中是通过ApplicationListener及ApplicationEventMulticaster来进行事件驱动开发的,即实现观察者设计模式或发布-订阅模式。
	 * ApplicationListener监听容器中发布的事件,只要事件发生,就触发监听器的回调,来完成事件驱动开发。属于观察者设计模式中的Observer对象。
	 * ApplicationEventMulticaster用来通知所有的观察者对象,属于观察者设计模式中的Subject对象。
	 */
	protected void initApplicationEventMulticaster() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();

		// 判断容器中是否存在applicationEventMulticaster
		// 也就是自定义的事件监听多路广播器,必须实现ApplicationEventMulticaster接口
		if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
			this.applicationEventMulticaster =
					beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
			if (logger.isDebugEnabled()) {
				logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
			}
		}
		else {
			// 如果没有,则默认采用SimpleApplicationEventMulticaster
			this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
			beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
			if (logger.isDebugEnabled()) {
				logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
						APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
						"': using default [" + this.applicationEventMulticaster + "]");
			}
		}
	}

 

9、onRefresh方法

查看代码
/**
	 * 模板方法,可以重写该方法以添加特定于上下文的刷新工作。
	 * 在初始化特殊bean时调用,然后实例化单例。
	 */
	protected void onRefresh() throws BeansException {
		// For subclasses: do nothing by default.
	}

 

10、registerListeners方法

查看代码
/**
	 * 添加实现ApplicationListener的bean作为监听器。
	 * 不会影响其他监听器,可以添加这些监听器而无需添加bean。
	 */
	protected void registerListeners() {
		// 首先注册静态指定的监听器
		for (ApplicationListener<?> listener : getApplicationListeners()) {
			getApplicationEventMulticaster().addApplicationListener(listener);
		}

		// 不要在这里初始化FactoryBean:我们需要保留所有常规Bean,未初始化以允许后处理器应用于它们!
		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
		for (String listenerBeanName : listenerBeanNames) {
			getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
		}

		// 发布早期应用程序事件现在我们终于有了一个multicaster
		Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
		this.earlyApplicationEvents = null;
		if (earlyEventsToProcess != null) {
			for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
				getApplicationEventMulticaster().multicastEvent(earlyEvent);
			}
		}
	}

 

11、 finishBeanFactoryInitialization 详情见Spring源码-IOC部分-Bean实例化过程【5】

查看代码
/**
	 * 完成此上下文的bean工厂的初始化,初始化所有剩余的单例bean。
	 */
	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// 1.初始化此上下文的转换服务
		if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
		}

		// 2.如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器:主要用于注解属性值的解析。
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// 3.初始化LoadTimeWeaverAware Bean实例对象
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class,
				false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		beanFactory.setTempClassLoader(null);

		// 4.冻结所有bean定义,注册的bean定义不会被修改或进一步后处理,因为马上要创建 Bean 实例对象了
		beanFactory.freezeConfiguration();

		// 5.实例化所有剩余(非懒加载)单例对象 (这一步很重要,bean的实例化是从这里开始的)
		beanFactory.preInstantiateSingletons();
	}

 

12、finishRefresh方法

查看代码
/**
     * 完成刷新工作
	 * 调用LifecycleProcessor的onRefresh方法并发布
	 */
	protected void finishRefresh() {

		// 清除上下文级别的资源缓存(例如来自扫描的ASM元数据)。
		clearResourceCaches();

		// 为此上下文初始化lifecycle processor。
		initLifecycleProcessor();

		// 首先将刷新传播到lifecycle processor。
		getLifecycleProcessor().onRefresh();

		// 发布事件
		publishEvent(new ContextRefreshedEvent(this));

		// 如果active,请参与LiveBeansView MBean。
		LiveBeansView.registerApplicationContext(this);
	}

 

参考资料:

《Spring5核心原理与30个类手写》作者 谭勇德

《Spring源码深度解析》作者 郝佳

《Spring技术内幕》作者 计文柯

posted on 2022-02-01 18:32  wzyy  阅读(204)  评论(0编辑  收藏  举报