Bean的生命周期
2021-12-02 21:50:52 1 举报
AI智能生成
登录查看完整内容
Bean的生命周期
作者其他创作
大纲/内容
bean的生命周期是指bean是如何创建、以及如何销毁的
组合了BeanDefinitionRegistry
从资源中加载多个BeanDefinition,并调用BeanDefinitionRegistry进行注册
AnnotatedBeanDefinitionReader根据class对象生成beanName和BeanDefinition,注册到容器中,会处理的注解有:@Conditional,@Scope,@Lazy,@Primary,@DepensOn
得到的是AnnotatedGenericBeanDefinition
BeanDefinitionReader
beanDefinition扫描器,实现类ClassPathBeanDefinitionScanner
根据包名扫描类路径下包以及子包的class文件得到BeanDefinition,调用BeanDefinitionRegistry进行注册
得到的是ScannedGenericBeanDefinition
@ComponentScan是通过它来实现的,要和@Configuaration一起,才会生效
读取class文件-->字节码解析得到MetadataReader-->过滤-->封装进ScannedGenericBeanDefinition-->生成beanName-->检查beanName重复-->注册进beanDefinitionMap
底层使用ASM字节码解析技术读取class文件,而不是类加载的方式读取到JVM中,最终得到的ScannedGenericBeanDefinition的beanClass是类名称而不是Class对象,避免包中的所有class类在启动时都被不必要地加载
lookup用于单例bean要注入多例的场景loopkup方法所在类可以是抽象类,spring都会为其生成cglib代理对象,loopup方法再代理对象中会使用context.getbean,因此原方法可以返回null
类的短名称:最后一个点号之后,cglib分隔符$$之前的,静态内部类$转成点号
详细流程
BeanDefinitionScanner
生成beanDefinition
org.springframework.beans.factory.support.AbstractBeanFactory#getMergedLocalBeanDefinition
包括父子BeanDefinition的合并和父子beanFactory的合并,合并就是子BeanDefinition中未设置的属性继承父BeanDefinition的
BeanDefinition可以有父BeanDefinition
父子beanFactory中beanName相同的BeanDefinition会合并
合并beanDefinition
org.springframework.beans.factory.support.AbstractBeanFactory#resolveBeanClass
bean实例化前要先类加载,beanDefinition中的beanClass属性是Object类型,在bean扫描生成beanDefinition阶段,该属性的值是类名,到这一步才会进行类加载,生成Class对象填充进去
类加载就是获取类加载器,再loadClass
类加载器的获取:优先使用beanFactory设置的类加载器,如果没有,获取当前线程的类加载器,还没有,获取当前类的类加载器,当前类的类加载器也为null时(当把当前类放到jre/lib,被bootstrap类加载器加载时),直接获取系统类加载器
加载类
调用bean的后置处理器的实例化前方法,InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation,返回不为空时,会直接使用返回值作为bean实例,并且跳过后续流程直接执行初始化后方法
实例化前
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance
supplier创建对象:如果BeanDefinition中设置了Supplier,直接调用Supplier的get()得到对象
检查BeanDefinition中是否设置了factoryMethod,可以通过xml的factory-method、factory-bean或@Bean设置
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#instantiateUsingFactoryMethod
可以是静态的或成员方法
静态方法,factoryBeanName是null,method.invoke(null)
如果出现方法重载,BeanDefinition.isFactoryMethodUnique==false,这时会获取factoryClass中所有factoryMethod名称相同的方法,然后走推断构造方法流程
@Bean可以是成员方法、静态方法,font color=\"#ff0000\
@Bean
工厂方法创建对象
会判断bean中是否有@Lookup方法,如果没有,使用反射调用构造器实例化bean,否则生成一个代理对象
如果有一个构造器有@Autowired.required=true,其他构造器就不能有@Autowired,否则报BeanCreationException
如果有多个不带@Autowired的构造器,则会用无参构造器,没有报错
如果只有一个@Autowired.required=false的构造器,且没有无参构造器,不报错,但日志输出single autowire-marked constructor flagged as optional,this constructor is effectively required since there is no default constructor to fall back to
如果只有一个有参不带@Autowired的构造器,则用该构造器
如果有多个不带@Autowired的构造器,返回空
如果只有一个无参构造器,返回空
AutowiredAnnotationBeanPostProcessor.determineCandidateConstructors
如果有多个候选构造器,先排序,Public的排前面,作用域相同时,参数多的排前面,参数相同的情况下如果还有多个,则对它们进行打分,打分根据注入参数类型和方法形参类型有几级继承得出,一级加2,得分越低,类型匹配度越高,优先级就越高
注入点名称是构造器参数名称,通过字节码局部变量表获得
ConstructorResolver.autowireConstructor
推断构造方法
实例化
MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition
Bean实例化之后,属性填充之前,可以查询或修改合并之后的BeanDefinition
实现类有:CommonAnnotationBeanPostProcessor,AutowiredAnnotationBeanPostProcessor,查找注入点,查询bean的@PostConstruct,@PreDestory,@Resource、@Autowired、@Value等注解标注的方法或成员变量信息,以便填充和初始化时调用
beandefinition的后置处理器
InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
没怎么使用
实例化后方法
InstantiationAwareBeanPostProcessor.postProcessProperties
根据刚才找到的注入点,查找创建依赖bean的实例,并注入
如果出现循环依赖,需要解决循环依赖
@Resource用在方法上时,只能注入第一个参数,注入点的名称就是去掉set前缀的方法名称,而@Autowired可以注入多个方法参数,并且名称是参数名称
依赖注入
BeanNameAware,BeanClassLoaderAware,BeanFactoryAware
内置的Aware也就是不通过后置处理器来实现的,不管用什么容器都一定能获取到的组件
spring内置的Aware
BeanPostProcessor.postProcessBeforeInitialization
InitDestroyAnnotationBeanPostProcessor会在初始化前这个步骤中执行@PostConstruct的方法
ApplicationContextAwareProcessor会在初始化前这个步骤中进行其他Aware的回调: ApplicationContextAware、EnvironmentAware、ResourceLoaderAware、MessageSourceAware(国际化)、ApplicationEventPublisherAware
初始化前
查看当前Bean对象是否实现了InitializingBean接口,如果实现了就调用其afterPropertiesSet()方法
初始化
BeanPostProcessor.postProcessAfterInitialization
最后一个步骤,对Bean进行最终处理,Spring中的AOP就是基于初始化后实现的,初始化后返回的对象才是最终的Bean对象
初始化后
bean的生成
bean的销毁是针对单例bean的,原型bean不会有销毁流程
有销毁方法的bean才会注册,销毁方法有哪些:DisposableBean.destroy、beanDefinition设置的destroyMethodName、AutoCloseable.close、beanDefinition.destroyMethodName是(infered)时,依次找close和shutdown、DestructionAwareBeanPostProcessor.requiresDestruction(bean)==true
注册实际上是用了适配器类DisposableBeanAdapter将bean封装起来,font color=\"#ff0000\
@PreDestroy方法实际上是通过DestructionAwareBeanPostProcessor实现的
创建Bean之后,注册销毁流程
容器关闭有2种方式:手动调用close、调registerShutdownHook向JVM注册关闭钩子线程,关闭逻辑2者相同
容器关闭时,会调用beanFactory.destroySingletons销毁单例bean
单例池和二级、三级缓存中移除单例bean-->递归销毁当前bean所依赖的所有对象-->调用bean的销毁方法
容器关闭调用销毁流程
Bean的销毁
Bean的生命周期
0 条评论
回复 删除
下一页