笔记大纲
Sping的容器启动和Bean工厂的初始化相关后续整理。
1.BeanDefinition的生成
1.1 包路径扫描
1.通过ResourcePatternResolve扫描指定包路径下的所有.class
文件。
2.每一个class文件在Spring中都抽象成Resource对象。
1.2 扫描解析Resource文件
1.利用MetadataReaderFactory解析Resource对象得到MetadatarReader对象。
2.解析过程采用的是ASM字节码技术,没有加载类。
1.3 MetadataReader筛选
1.MetadataReader拥有类的所有信息,通过判断类上是否带有@Conditional注解来筛选。
2.如果类上有条件注解,或者有excludeFilters等过滤表达式,则匹配的类就直接抛弃。
1.4 BeanDefinition的创建
1.如果筛选通过,那么这个class就是一个需要被Spring管理。
2.MetadataReader生成这个类的ScannedGenericBeanDefinition并加入BeanDefinition集合。
2.BeanDefinition的合并
BeanDefinition存在父子关系,BeanDefinition可以继承其它的BeanDefinition,那么此时就会创建新的BeanDefinition,将父子BeanDefinition合并。
3.类加载
当一个类有了自己的BeanDefinition,那么就可以基于BeanDefinition生成SpringBean了,在创建对象之前肯定需要类加载,因为包扫描的时候是基于ASM字节码技术。
1.AbstractAutowireCapableBeanFactory # createBean( )方法执行。
2.首先获取BeanFactory设置的类加载器,如果没有设置则使用默认的类加载器。
3.默认的类加载器调用ClassUtils.getDefaultClassLoader( )返回。
4.这个工具类优先返回当前线程上下文的ClassLoader。
5.如果当前线程上下文没有设置类加载器,则返回ClassUtils这个类的类加载器。
6.如果ClassUtils的类加载器为空(一般不会有这种情况,除非把这个类移到rt.jar包下交给BootStrap加载 器),则说明这类是BootStrapClassLoader。
4.实例化前
在实例化创建对象之前,Spring提供了拓展点,基于postProcessor机制来做一些前后操作。
InstantiationAwareBeanPostProcessor # postProcessBeforeInstantiation( )
方法会被执行,每个SpringBean实例化前都会执行它(这个拓展点写死在Spring源码中)。
这个方法的入参是实例化这个对象的Class对象和BeanName,返回值是Object,当然也可以返回null。如果自己new了一个这个类的对象,那么当前实例化的Bean就不会依赖注入等操作,直接快进到初始化后的流程。
5.实例化
5.1 工厂方法创建对象
根据BeanDefinition的描述创建对象。
1.如果BeanDefinition的factoryMethod属性有值,则调用这个属性值的工厂方法来创建对象。
2.如果BeanDefinition的supplier属性有值,则调用Supplier#get( )方法返回对象。
5.2 构造方法的推断
如果该类没有写构造方法,那么Spring就是用无参构造。如果这个类有多个构造,并且没有加类似@Autowired的注解来指定用哪个构造,那么Spring会进行构造推断过程:
1.如果类只有1个构造方法,Spirng就调用这个构造。
2.如果类存在多个构造,且未指定,那么Spring判断这几个构造里是否有无参构造,如果有则调用。如果没有,Spring就会抛异常。
6.BeanDefinition的后置处理
当Bean对象实例化创建出来以后,就可以给对象的属性赋值。在赋值之前,会基于postProcessor机制对BeanDefdition进行拓展。
MergedBeanDefinitionPostProcessor # postProcessMergedBeanDefinition()
这个方法会被调用,入参有BeanDefinition,可以对BeanDefinition进行操作。
7.实例化后
和实例化前
类似,基于postProcessor机制的拓展功能,在Bean对象实例化后也有后置处理器。
InstantiationAwareBeanPostPorcessor # postProcessAfterInstantiation()
方法被执行,入参就是实例化后的Bean对象和BeanName,可以对Bean对象进行额外的自定义操作。不过这个拓展点Spring内部没有使用。
8.属性注入
对@Autowired、@Resource、@Value等注解的处理,底层基于postProcessor机制完成。
9.各种基础Aware接口的回调
- BeanNameAware
- BeanClassLoaderAware
- BeanFactoryAware等
10.初始化前
1.(重点)基于BeanPostProcessor # postProcessBeforeInitialization()
拓展机制进行 初始化前的业务自定义处理,入参是已经有属性的Bean,返回值也是这个Bean。
2.@PostConstruct的执行
3.ApplicationContextAwareProcessor执行其它Aware的回调:
- ResourceLoaderWare
- MessageSourceAware
- ApplicationEventPublisherAware等
11.初始化
- 检查该类是否实现了InitializingBean接口,如果实现了,就调用afterPropertiesSet( )。
- 执行BeanDefinition中指定的init-method初始化方法。
12.初始化后
基于BeanPostProcessor # postProcessAfterInitialization()
拓展机制调用,实现自定义的操作,入参和返回值都是当前Bean。
Spring的AOP操作也是基于初始化后postProcessor实现的。
Bean的销毁
当容器调用close( )
方法时,Spring容器就会进行关闭的流程。在Bean对象初始化后阶段,Spring
会检查该Bean是否实现了DisposableBean接口或者实现了AutoCloseable接口或者BeanDefinition中指定了destroyMethod方法、有@PreDestroy注解。
如果符合其中之一,就把Bean封装成一个DisposableBeanAdapter对象,存入DisposableBeans这个Map中,以备后续关闭的时候使用。
在容器销毁的时候:
- spring发布ContextClosedEvent事件
- onClose( )方法被触发
- 遍历DisposableBeans这个Map,挨个儿从单例池中移除,调用Bean的销毁方法。