Spring Bean 的创建

前几篇文章我们对Spring的启动流程进行了梳理,了解了Spring容器启动的, 但是我们没有对bean的创建进行介绍,本文将对bean的创建进行分析; 如果您对Spring的启动还不了解,请先阅读文章SpringApplication 运行及源码解读

起源refresh()

书接上回,我们还是回到refesh()方法,这是一个神奇的方法,让我们回顾一下

@Override
public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		// 准备刷新此上下文。(记录下容器的启动时间、标记“已启动”状态、处理配置文件中的占位符等)
		prepareRefresh();
        // 告诉子类刷新内部bean工厂。
        // 这步比较关键,这步完成后,配置文件就会解析成一个个 Bean 定义,注册到 BeanFactory 中,
        // 当然,这里说的 Bean 还没有初始化,只是配置信息都提取出来了,
        // 注册也只是将这些信息都保存到了注册中心(说到底核心是一个 beanName-> beanDefinition 的 map)
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
		// 准备BeanFactory以供在此上下文中使用。
		prepareBeanFactory(beanFactory);

		try {
			//允许在上下文子类中对bean工厂进行后处理。
            // 【这里需要知道 BeanFactoryPostProcessor 这个知识点,Bean 如果实现了此接口,
            // 那么在容器初始化以后,Spring 会负责调用里面的 postProcessBeanFactory 方法。】
            // 这里是提供给子类的扩展点,到这里的时候,所有的 Bean 都加载、注册完成了,但是都还没有初始化
            // 具体的子类可以在这步的时候添加一些特殊的 BeanFactoryPostProcessor 的实现类或做点什么事
			postProcessBeanFactory(beanFactory);
			// 在上下文中调用注册为bean的工厂处理器。
			invokeBeanFactoryPostProcessors(beanFactory);
			// 注册拦截bean创建的bean处理器。
            // 注册 BeanPostProcessor 的实现类,注意看和 BeanFactoryPostProcessor 的区别
            // 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
            // 两个方法分别在 Bean 初始化之前和初始化之后得到执行。注意,到这里 Bean 还没初始化
			registerBeanPostProcessors(beanFactory);
			// 初始化国际化
			initMessageSource();
			// 为此上下文初始化事件多宿主。
			initApplicationEventMulticaster();
			// 从方法名就可以知道,典型的模板方法(钩子方法),
            // 具体的子类可以在这里初始化一些特殊的 Bean(在初始化 singleton beans 之前)
			onRefresh();
			registerListeners();
            //  本文的重点方法
			// 实例化所有剩余的(非延迟初始化)单例。
			finishBeanFactoryInitialization(beanFactory);
			// 进行广播,完成实例化
			finishRefresh();
		}
		catch (BeansException ex) {
			if (logger.isWarnEnabled()) {
				logger.warn("Exception encountered during context initialization - " +"cancelling refresh attempt: " + ex);
			}
			destroyBeans();
			cancelRefresh(ex);
			throw ex;
		}
		finally {
			resetCommonCaches();
		}
	}
}

CreateBean

  • doGetBean()

  • createBean()

  • doCreateBean()

  • createBeanInstance()

  • instantiateBean()

到这里,我们就算实例化完成了。我们开始说怎么进行属性注入。

bean属性注入

对于属性的设置,这里有一个非常重要的类就是RootBeanDefinition,当我阅读RootBeanDefinition时会发现它其实时BeanDefinition 的渐接的子类,关于BeanDefinition的介绍,请阅读Spring BeanDefinition 详解

initializeBean

初始化给定的bean实例,应用工厂回调、init方法和bean后处理程序。 对于传统定义的bean,从{@link#createBean}调用,对于现有的bean实例从{@link#initializeBean}调用。

到这里关于bean的创建就分析完了,不足之处还请大家多多指

Last updated

Was this helpful?