Spring:IOC容器到底是咋肥事啊?

Posted Imaginary

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring:IOC容器到底是咋肥事啊?相关的知识,希望对你有一定的参考价值。

菜瓜:哥,他们整天说的IOC容器是个啥玩意啊?

水稻:就是Inversion of Control,控制反转啊

菜瓜:哦,原来是控制反转啊,我知道了!你这不是等于白说吗?

水稻:别急,听我慢慢说:

  • 想象一下我们平时写测试类,如果不用Spring,我们在A对象里面引用B对象,是不是要自己创建或者引用B,这些操作都是由A来触发的。
  • 而如果使用Spring,A需要B的话,直接使用@Autowired注解注入B开箱即用,A不在管B的创建啥的,只需要有个装B的容器给A分配就行了。

菜瓜:就是A引用B本来由自己创建的,结果变成了单位分配对象了。而且如果有多个对象之间存在引用关系就省了好多代码

水稻:deideidei,那你知道Spring的IOC容器初始化是咋做的吗?

菜瓜:你猜我猜不猜?

水稻:Spring启动的过程其实也是IOC容器初始化的过程,如果你不想知道spring的启动过程,那SpringBoot你肯定想知道

  • Spring有一个上下文抽象类AbstractApplicationContext,假设你看过SpringBoot的启动类源码(你点一下那个run方法跟进去慢慢找,就能找到)能找到它默认加载了AnnotationConfigApplicationContext子类,然后调用了AbstractApplicationContext的refresh方法。
  • 先看AnnotationConfigApplicationContext。你知道的@Autowired@Resource@ComponentScan@Bean@Import@Configuration注解的功能解析类都是从它这里注册的。初始化它的时候会调用方法AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);该方法会注册BeanFactoryPostProcessor和BeanPostProcessor接口实现类到BeanDefinitionNames中,最为关键的ConfigurationClassPostProcessor为SpringBoot启动类上的注解提供了支撑
  • 再回过头来看refresh方法,挑重要的讲,它会实例化BeanFactoryPostProcessor接口实现类ConfigurationClassPostProcessor并解析@Configuration和@Import@ComponentScan注解
    • 回头看SpringBoot启动类上的@SpringBootApplication注解
    • @ComponentScan注解:ConfigurationClassPostProcessor在解析该注解时会通过一个扫描类扫描指定路径下的class文件,将所有带有@Component注解的类搜集到BeanDefinitionNames容器中,方便后面实例化
    • @SpringBootConfiguration注解:标识该类被IOC容器管理
    • @EnableAutoConfiguration:Imoprt了AutoConfigurationImportSelector类。该类回去加载META-INFO/spring.factories文件里面的类,包括有web容器,默认配置等

菜瓜:我懵逼了,这A和B的创建还没开始,你整这么多我不知道的东西干啥?

水稻:我的,我的。上面讲的是SpringBoot的启动流程,是IOC容器的准备阶段。你可以略过,我们进入IOC正式阶段

  • 概括下来就是,Spring会通过扫描器的形式去扫描我们指定包路径下的.class文件(SpringBoot没配置的情况下,默认是启动类所在包,你要是不小心将启动类挪走了,你会发现扫描不到文件)。将带有@Component注解(包括其子类)的类封装成BeanDefinition加入一个大的BeanDefinitionMap容器中,与之对应的还有一个BeanDefinitionNames
  • 之后会for循环这个BeanDefinitionNames,单独加载每一个类,放入IOC容器,也就是一个大的ConcurrentMap中

菜瓜:哦,你这么说我就能听懂了。那他们说的循环依赖,很多的BeanPostProcessor还没介绍呢?

水稻:溜了溜了,你等我吃完饭回来再和你说

        

 

以上是关于Spring:IOC容器到底是咋肥事啊?的主要内容,如果未能解决你的问题,请参考以下文章

1.3浅谈Spring(IOC容器的实现)

Spring IOC源码剖析:Spring IOC容器初始化主体流程

spring IoC容器的实现。

Spring ioc容器

Spring IOC容器

Spring IOC容器