SpringBoot启动过程深度解析——Bean的创建过程以及扩展点

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创建过程逻辑图

SpringBoot启动过程深度解析——Bean的创建过程以及扩展点_第1张图片


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方法】

你可能感兴趣的:(spring,java,spring,boot,架构,后端)