SpringIOC加载过程

今天详细学习了一遍SpringIOC加载过程,将网上搜集到的信息进行了下整理,期望能对您起到帮助。
本文大部分取自影公子的博客他写得十分详细。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

加载容器

ApplicationContext context = new ClassPathXmlApplicationContext("classpath:application.xml");

进行ClassPathXmlApplicationContext的refresh()方法

@Override
public void refresh() throws BeansException, IllegalStateException {
   // 来个锁,不然 refresh() 还没结束,你又来个启动或销毁容器的操作,那不就乱套了嘛
   synchronized (this.startupShutdownMonitor) {

      // 准备工作,记录下容器的启动时间、标记“已启动”状态、处理配置文件中的占位符
      prepareRefresh();

      // 这步比较关键,这步完成后,配置文件就会解析成一个个 Bean 定义,注册到 BeanFactory 中,
      // 当然,这里说的 Bean 还没有初始化,只是配置信息都提取出来了,
      // 注册也只是将这些信息都保存到了注册中心(说到底核心是一个 beanName-> beanDefinition 的 map)
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // 设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor,手动注册几个特殊的 bean
      prepareBeanFactory(beanFactory);

      try {
         // 这里需要知道 BeanFactoryPostProcessor 这个知识点,Bean 如果实现了此接口,
         // 那么在容器初始化以后,Spring 会负责调用里面的 postProcessBeanFactory 方法。

         // 这里是提供给子类的扩展点,到这里的时候,所有的 Bean 都加载、注册完成了,但是都还没有初始化
         // 具体的子类可以在这步的时候添加一些特殊的 BeanFactoryPostProcessor 的实现类或做点什么事
         postProcessBeanFactory(beanFactory);
         // 调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 回调方法
         invokeBeanFactoryPostProcessors(beanFactory);          
          
         // 注册 BeanPostProcessor 的实现类,注意看和 BeanFactoryPostProcessor 的区别
         // 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
         // 两个方法分别在 Bean 初始化之前和初始化之后得到执行。这里仅仅是注册,之后会看到回调这两方法的时机
         registerBeanPostProcessors(beanFactory);

         // 初始化当前 ApplicationContext 的 MessageSource,国际化
         initMessageSource();

         // 初始化当前 ApplicationContext 的事件广播器
         initApplicationEventMulticaster();

         // 从方法名就可以知道,典型的模板方法(钩子方法)
         // 具体的子类可以在这里初始化一些特殊的 Bean(在初始化singletonbeans之前)
         onRefresh();

         // 注册事件监听器,监听器需要实现 ApplicationListener 接口。
         registerListeners();

         // 重点,重点,重点
         // 初始化所有的 singleton beans
         //(lazy-init 的除外)
         finishBeanFactoryInitialization(beanFactory);

         // 最后,广播事件,ApplicationContext 初始化完成
         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.
         // 销毁已经初始化的 singleton 的 Beans,以免有些 bean 会一直占用资源
         destroyBeans();

         // Reset 'active' flag.
         cancelRefresh(ex);

         // 把异常往外抛
         throw ex;
      }

      finally {
         resetCommonCaches();
      }
   }
}
(1)synchronized:为代码块加锁,防止并发占用
(2)prepareRefresh():做准备工作的,记录容器的启动时间、标记“已启动”状态、处理配置文件中的占位符
(3)ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory():配置文件解析成一个个Bean,并且注册到BeanFactory中,注意这里只是注册进去,并没有初始化。beanName-> beanDefinition 的 map
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
	refreshBeanFactory();
    //返回刚刚创建的BeanFactory
	ConfigurableListableBeanFactory beanFactory = getBeanFactory();
	if (logger.isDebugEnabled()) {
		logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
	}
	return beanFactory;
}
① refreshBeanFactory():关闭旧的 BeanFactory (如果有),创建新的 BeanFactory,加载 Bean 定义、注册 Bean 等
@Override
protected final void refreshBeanFactory() throws BeansException {
    //如果之前有BeanFactory,销毁所有bean,删除BeanFactory
	if (hasBeanFactory()) {
		destroyBeans();
		closeBeanFactory();
	}
	try {
        //初始化功能最大的BeanFactory
		DefaultListableBeanFactory beanFactory = createBeanFactory();
		//序列化
        beanFactory.setSerializationId(getId());
        //是否允许 Bean 覆盖、是否允许循环引用**
		customizeBeanFactory(beanFactory);
        //根据配置,加载各个 Bean,然后放到 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);
	}
}
(4)实现了 BeanFactoryPostProcessor 接口的 Bean 都已经初始化并且其中的 postProcessBeanFactory(factory) 方法已经得到回调执行了。而且 Spring 已经“手动”注册了一些特殊的 Bean,如 ‘environment’、‘systemProperties’ 等。
(5)finishBeanFactoryInitialization(beanFactory):初始化所有的 singleton beans。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
	// 注册这个bean之后,类似于前端传给后端的非基础类型和基础类型的包装类之外,其他的就可以考虑采用ConversionService来进行类型等的转换
	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));
	}

	// Register a default embedded value resolver if no bean post-processor
	// (such as a PropertyPlaceholderConfigurer bean) registered any before:
	// at this point, primarily for resolution in annotation attribute values.
	if (!beanFactory.hasEmbeddedValueResolver()) {
		beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
	}

	// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
	String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
	for (String weaverAwareName : weaverAwareNames) {
		getBean(weaverAwareName);
	}

	// Stop using the temporary ClassLoader for type matching.
	beanFactory.setTempClassLoader(null);

	// Allow for caching all bean definition metadata, not expecting further changes.
	beanFactory.freezeConfiguration();

	// Instantiate all remaining (non-lazy-init) singletons.
	beanFactory.preInstantiateSingletons();
}

① beanFactory.preInstantiateSingletons()

this.beanDefinitionNames 保存了所有的 beanNames,然后再循环,判断非抽象、非懒加载的 singletons,如果是FactoryBeanFactoryBean 的话,在 beanName 前面加上 ‘&’ 符号,再调用getBean(beanName);,如果是普通的bean,那么直接getBean(beanName);,这里都是在循环中的,循环结束后,所有的非单例bean就初始化完成了

getBean()->createBean(beanName, mbd, args)->Object beanInstance = doCreateBean(beanName, mbdToUse, args)->createBeanInstance(beanName, mbd, args):实例化Bean

  • 首先确保已经加载过这个class

  • 然后检验一下权限

  • 采用工厂方法实例化

  • 工厂方法不行->构造函数依赖注入->无参构造函数:那说明不存在方法覆写,使用 java 反射进行实例化,如果不进入使用 CGLIB进行实例化

populateBean(beanName, mbd, instanceWrapper):属性注入

  • 通过名字找到所有属性值,如果是 bean 依赖,先初始化依赖的 bean。记录依赖关系。
  • 名字找不到则通过类型装配
  • 对采用 @Autowired、@Value 注解的依赖进行设值
  • 设置 bean 实例的属性值了到这里,属性注入就完成了

总结:

初始化容器

  1. Application加载xml
  2. AbstractApplicationContext的refresh函数载入Bean定义过程

创建BeanFactory

  1. AbstractApplicationContext子类的refreshBeanFactory()方法

注册BeanDefinitions至BeanFactory

  1. AbstractRefreshableApplicationContext子类的loadBeanDefinitions方法
  2. AbstractBeanDefinitionReader读取Bean定义资源
  3. 资源加载器获取要读入的资源
  4. XmlBeanDefinitionReader加载Bean定义资源
  5. DocumentLoader将Bean定义资源转换为Document对象
  6. XmlBeanDefinitionReader解析载入的Bean定义资源文件
  7. DefaultBeanDefinitionDocumentReader对Bean定义的Document对象解析
  8. BeanDefinitionParserDelegate解析Bean定义资源文件中的元素
  9. BeanDefinitionParserDelegate解析元素
  10. 解析元素的子元素
  11. 解析子元素
  12. 解析过后的BeanDefinition在IoC容器中的注册(IoC容器的初始化结束)

实例化Bean

  1. DefaultListableBeanFactory向IoC容器注册解析后的BeanDefinition(依赖注入开始)
  2. AbstractBeanFactory通过getBean向IoC容器获取被管理的Bean
  3. AbstractAutowireCapableBeanFactory创建Bean实例对象
  4. createBeanInstance方法创建Bean的java实例对象
  5. SimpleInstantiationStrategy类使用默认的无参构造方法创建Bean实例化对象

Bean属性注入

  1. populateBean方法对Bean属性的依赖注入
  2. BeanDefinitionValueResolver解析属性值
  3. BeanWrapperImpl对Bean属性的依赖注入
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值