SpringBoot启动过程深度解析——Bean的创建过程以及扩展点
Bean生命周期的扩展点:
1.重写Bean类中的方法:
【为什么要提供此扩展点?当单例Bean引用了多例Bean时,返回的是单例Bean,这是一个BUG。需要提前进行CGlib代理,后续通过getBean获取多例属性Bean】
【为了解决类似问题的有:configurationClassPostProcessor 也是为了解决 @Bean是多例的情况,而提前进行代理,后续通过GetBean获取生成多例Bean 【enhanceConfigurationClasses方法】】
lookup-method、replace-method
2.Bean实例化的方式有以下几种:
【直接返回Bean,不经过初始化的详细流程】 实现factoryBean 【直接对象】 【相当于重写了createBean方法,替代createBean方法直接返回对象】
【直接返回Bean,不经过初始化的详细流程】 实现InstantiationAwareBeanPostProcessor 【直接对象】 【在createBean方法中调用,在doCreateBean之前调用,直接返回对象】
【需要经历初始化的详细流程】 向BeanDefinition设置自定义supplier 【只是实例化,创建BeanWrapper封装在里面】【创建一个BeanFactoryPostProcessor,设置对应BeanDefinition的setSupplier,后续在doCreateBean方法调用createBeanInstance】
【需要经历初始化的详细流程】 实现factoryMethod 【只是实例化,创建BeanWrapper封装在里面】【在配置类中@Bean注解的方法如果是static修饰的,那么这种bean的实例化就是通过FactoryMethod实现的。】
【需要经历初始化的详细流程】 正常spring创建流程 【通过反射实例化原对象和代理对象】
3.BeanPostProcessor【普通的处理器接口】
接口方法1:postProcessBeforeInitialization(在Bean实例化之前调用)
接口方法2:postProcessAfterInitialization(在Bean实例化之后调用)
此接口的子类接口:
1.DestructionAwareBeanPostProcessor 【销毁Bean前调用】
1.postProcessBeforeDestruction方法:在调用Bean的Destroy方法前调用
2.InstantiationAwareBeanPostProcessor 【spring用于抑制某些Bean的创建: 代理、延迟初始化、字段注入、注解增强... 如果自己要实现这种类型,请实现这个 InstantiationAwareBeanPostProcessorAdapter】
1.【实例化后】resolveAfterInstantiation方法
2.【实例化前】resolveBeforeInstantiation方法:还没doCreateBean的时候调用:AbstractAutowireCapableBeanFactory.createBean() 【此处 先执行before方法 如果通过此方法返回了Bean,则直接执行after的方法】
3.【初始化前】postProcessBeforeInitialization方法
4.【初始化后 一般用于设置属性】postProcessAfterInitialization方法
5.【属性值处理】postProcessProperties方法:在populateBean方法时,先执行
6.【属性值处理】postProcessPropertyValues方法:在populateBean方法时,如果postProcessProperties 放回null ,则会执行
3.MergedBeanDefinitionPostProcessor 【用于合并父类的BeanDefinition信息 】
1.postProcessMergedBeanDefinition方法 :doCreateBean的时候调用(instanceWrapper之后,populateBean之前)
2.resetBeanDefinition方法
4.SmartInstantiationAwareBeanPostProcessor【继承MergedBeanDefinitionPostProcessor】
1.【预测某些Bean的类型】predictBeanType方法
2.【创建Bean时,自定义返回对应的构造器】determineCandidateConstructors方法:在createBeanInstance方法获取构造器时,就会调用此方法返回特殊的构造方法
3.【解决循环依赖问题,创建代理对象Bean】getEarlyBeanReference方法
【提前暴露代理生成方法,三级缓存】createBean方法 -> 实例化之后,初始化之前调用 -> addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
【当三级缓存的方法被调用时才会调用当前接口方法】() -> getEarlyBeanReference(beanName, mbd, bean)
【最终的调用地方:】遍历所有的SmartInstantiationAwareBeanPostProcessor方法getEarlyBeanReference
5.InitDestroyAnnotationBeanPostProcessor 【主要处理@PreDestroy 和 @PostConstruct】
4.@PostConstruct
被声明的方法将在执行完BeanPostProcessor的postProcessBeforeInitialization方法之后,马上执行该方法
5.InitializingBean【实例化Bean回调接口】
接口方法:afterPropertiesSet(在Bean设置完属性值之后调用)
6.@Bean(initMethod="xxxMethodName")
被声明的方法将在执行完InitializingBean的afterPropertiesSet方法之后,马上执行该方法
7.@PreDestroy
被声明的方法将在正常销毁Bean时,调用执行
8.@Bean(destroyMethod="xxxMethodName")
被声明的方法将在正常销毁Bean时,调用执行
Bean创建过程逻辑图
![请添加图片描述](https://i-blog.csdnimg.cn/blog_migrate/07362f3965004367b141ffee81e1edd0.png)
Bean创建过程文字描述逻辑
spring启动创建Bean标准入口:
refresh() # finishBeanFactoryInitialization()
preInstantiateSingletons()方法主要逻辑:
1.准备类型转换器 DefaultConversionService
2.内置的值的处理器 StringValueResolver
3.加载时织入增强器 LoadTimeWeaverAware
4.禁止使用临时类加载器进行类型匹配
5.冻结所有的bean定义,说明注册的bean定义将不被修改或任何进一步的处理
6.调用preInstantiateSingletons(); 实例化剩下的单例对象
【Bean创建入口】preInstantiateSingletons(); 实例化剩下的单例对象方法逻辑:
遍历集合的对象【所有非延迟非抽象单例bean】
1.合并父类BeanDefinition
2.【创建FactoryBean】
2.1 通过"&"+BeanName创建
2.2 判断是否饥饿加载Bean,通过调用getBean(BeanName) 注册工厂Bean生成的Bean实例
3.【创建普通Bean开始】
-> 【getBean方法开始调用】
-> 【doGetBean方法开始调用】
3.1 转换beanName (1.去除&符号 2.从aliasMap得到最终的BeanName)
3.2 判断是否已经存在一、二、三级缓存对象
-> 获取FactoryBean接口的对象
3.3 不存在缓存对象
-> 检查当前单例对象是否在创建过程中
-> 【先获取当前容器的BeanDefinition,如果没有就直接通过父容器 getBean】
-> 标记正在创建
-> 合并父类BeanDefinition
-> 检查mbd的合法性\抽象类抛异常
-> 【处理@DependOn,优先实例化依赖的bean】
-> 【递归优先实例化被依赖的Bean】
-> 【单例Bean创建】
-> 【getSingleton方法开始调用】
-> 一级缓存加锁
-> 判断不存在一级缓存,没有销毁中
-> 加入创建中集合
-> 【调用createBean / 调用FactoryBean的方法】
-> 通过BeanName解析成Class对象
-> 【标记重写方法,不限于lookup-method、replace-method】
-> 【直接返回Bean对象,结束.调用InstantiationAwareBeanPostProcessor】
-> 【先调用 applyBeanPostProcessorsBeforeInstantiation】
->【AOP 代理的生成 :实现类:AbstractAutoProxyCreator】
-> 【得到bean不为空,调用 applyBeanPostProcessorsAfterInitialization】
-> 【doCreateBean方法的调用】
-> 【创建BeanWrapper】
->【如果有InstanceSupplier,执行返回】
->【如果有FactoryMethod,执行返回】
->【bean构造器解析缓存就使用,执行返回】
-> 如果是autowire 使用ConstructorResolver.autowireConstructor最终调用 instantiationStrategy.instantiate
-> 非autowire 使用默认的 instantiationStrategy.instantiate
->【通过BeanPostProcessor获取的构造器】
-> (主要是匹配@Autowire注释的构造器)【调用SmartInstantiationAwareBeanPostProcessor接口的determineCandidateConstructors方法返回构造器】
->【如果是autowire的构造器,执行返回,ConstructorResolver.autowireConstructor】
->【处理@Primary的构造器,执行返回,ConstructorResolver.autowireConstructor】
->【使用默认无参的构造器实例化对象,执行返回,SimpleInstantiationStrategy.instantiate】
->【beanPostProcessor去修改合并的beanDefinition】
-> 【MergedBeanDefinitionPostProcessor接口实现类执行postProcessMergedBeanDefinition方法】(主要处理@
-> 实现类:CommonAnnotationBeanPostProcessor 实现了 InitDestroyAnnotationBeanPostProcessor
1.【不是调用】主要是获取 @PostConstruct 注释的方法,并排序【@PostConstruct 父类优先执行】 -> 这个注解是JDK的
2.【不是调用】主要是获取 @PreDestroy 注释的方法,并排序【@PreDestroy 子类优先执行】 -> 这个注解是JDK的
3. 向BeanDefinition设置 ExternallyManagedInitMethod = init 、 ExternallyManagedDestroyMethod
4.【获取@Resource @WebServiceRef @EJB 父类优先注册的信息属性和方法 】
5. 向BeanDefinition设置 ExternallyManagedConfigMember = xxx
-> 实现类:AutowireAnnotationBeanPostProcessor
4.【获取@Autowire @Value @Inject 父类优先注册的信息】
5. 向BeanDefinition设置 ExternallyManagedConfigMember = xxx
->【三级缓存,判断当前bean是否需要提前曝光:单例&允许循环依赖&当前bean正在创建中,检测循环依赖】
->【三级缓存添加,提前暴露代理/创建Bean的方法】
【三级缓存存放的是 getEarlyBeanReference方法,其中被其他Bean引用而被调用创建时,getSingleton方法,来调用该匿名方法来返回代理/原对象】
(【AOP处理】在getEarlyBeanReference方法中,会执行SmartInstantiationAwareBeanPostProcessor的方法getEarlyBeanReference)
->【populateBean 对bean的属性进行填充】
->【一般用于设置属性 可直接return; 如果有此实现类:InstantiationAwareBeanPostProcessor,会执行接口方法postProcessAfterInstantiation】【这里如果返回FALSE,直接返回】
-> 声明和获取mbd中的PropertyValues
->【处理XML的 autowire的属性值,1.byName 2.byType】
-> byName【可以处理集合指定的特定类型】
-> byType【可以处理集合指定的特定类型】
->【处理注解值 执行InstantiationAwareBeanPostProcessor接口方法:postProcessProperties】
->【AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor会执行】
->【@Autowire、@Value、@Resource、@Inject、@WebServiceRef、@EJB 会在此注入,和创建对应的属性Bean】
->【执行InstantiationAwareBeanPostProcessor接口方法:postProcessPropertyValues】
->【依赖检查】
->【根据property的标签的属性值,完成各种属性值的解析和赋值工作 applyPropertyValues方法】
->【此处如果循环依赖,开始加载创建中的Bean】
->【调用getSingleton方法获取】
->【AOP等处理,从三级缓存中执行getEarlyBeanReference方法,返回早期对象】
->【移除三级缓存,存放二级缓存!!!!】
->【initializeBean 执行初始化逻辑】
->【Aware接口处理器,调用BeanNameAware、BeanClassLoaderAware、beanFactoryAware】
->【BeanPostProcessor接口的postProcessBeforeInitialization执行】
->【ApplicationContextAwareProcessor】【设置EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware】
->【ConfigurationClassPostProcessor#ImportAwareBeanPostProcessor】【处理ImportAware接口中,注解信息的修改】
->【CommonAnnotationPostProcessor】【调用@PostConstruct的方法,也就是init方法】
-> ... ...
->【调用初始化方法】
->【InitializingBean接口的方法afterPropertiesSet】
->【在bean上调用指定的自定义init方法,从mbd.getInitMethodName()来执行,也就是@Init方法,@Pre】
->【BeanPostProcessor接口的postProcessAfterInitialization执行】
->【ApplicationListenerDetector】【如果是ApplicationListener接口实现的话,需要注册到多播器中】
->【循环依赖的检测,如果还有依赖的Bean还没创建,就会抛异常】
【只有二级缓存时,会在此报异常, A有代理B,代理B没有A,原B有A】
->【可以在此注册Bean工作,1.实现了DisposableBean接口,2.自定义destroy-method,3.DestructionAwareBeanPostProcessor处理销毁】
->【如果是单例,可以注册销毁一些销毁方法】
->【如果是其他作用域的Bean,则注册一个销毁的回调方法】
->【Bean创建结束】
->【Bean创建结束】
->【将单例标记为不在创建中】
->【一级缓存存放,移除三级缓存,移除二级缓存,BeanName注册到单例集合中】
->【Bean创建结束】
->【如果是FactoryBean会直接返回getObject方法实例】
->【如果是原型模式的创建】
->【标记创建中】
->【createBean】
->【取消创建中】
->【如果是FactoryBean会直接返回getObject方法实例】
->【如果是其他作用域的Bean的创建】
->【标记创建中】
->【createBean】
->【取消创建中】
->【如果是FactoryBean会直接返回getObject方法实例】
->【检查requiredType是否与实际Bean实例的类型匹配】
->【获取TypeConverter进行转换】
->【Bean创建结束】
->【Bean创建结束】
遍历beanNames,触发所有SmartInitializingSingleton的后初始化回调
1.【触发所有SmartInitializingSingleton的Bean的afterSingletonsInstantiated方法】