Spring IOC之Singleton Bean创建以及BeanPostProcessor调用源码分析

2022-10-09 12:55:46

一、版本

<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>4.3.12.RELEASE</version></dependency>

二、接口详解

2.1 什么是BeanPostProcessor?

BeanPostProcessor也称为Bean后置处理器,在Spring容器的创建过程中(具体为Bean初始化前后)会回调BeanPostProcessor中定义的两个方法。

publicinterfaceBeanPostProcessor{// 在bean初始化回调(例如InitializingBean的afterPropertiesSet或自定义init-method)之前调用
    ObjectpostProcessBeforeInitialization(Object bean, String beanName)throws BeansException;// 在bean初始化回调(例如InitializingBeanafterPropertiesSet或自定义init-method)之后调用
    ObjectpostProcessAfterInitialization(Object bean, String beanName)throws BeansException;}

其中,可以向IOC容器添加多个BeanPostProcessor(后置处理器),默认情况下容器加载次序决定了BeanPostProcessor调用顺序,也可以实现Ordered{@code getOrder}改变调用次序,其中getOrder返回值越大优先级越高。

publicinterfaceOrdered{int HIGHEST_PRECEDENCE= Integer.MIN_VALUE;int LOWEST_PRECEDENCE= Integer.MAX_VALUE;intgetOrder();}

2.2 BeanPostProcessor有什么作用?

提出一个问题:假设需要在Spring初始化Bean之后做一些定制化逻辑,简单如记录下Bean的初始化记录,或针校验Bean逻辑,又或者是针对某类策略需要执行一些具体的业务逻辑,那么怎么做比较好呢?

其实,Spring在初始化Bean之后已经加入了一些钩子方法,方便开发一些特定的后置业务处理逻辑,这也提现了AOP思想,其中钩子包括:

  • BeanPostProcessor
  • InitializingBean和DisposableBean
  • @PostConstruct、@PreDestroy
  • @Bean(initMethod、destroyMethod)

总结作用为:在Bean对象在实例化和依赖注入完毕后,在显示调用初始化方法的前后添加特定的业务逻辑。

2.3 为什么要注册BeanPostProcessor?

所谓的注册,只不过是对当前上下文中所有的BeanPostProcessor进行一种集中式管理罢了, 为什么非得这么做呢?
因为上下文中BeanPostProcessor的数量不是一成不变的,Spring为了启动的正常,需要添加原生的BeanPostProcessor,程序员因为自己的需求也会添加不同数量的Bean后置处理器,因此需要这种策略,将上下文中所有的后置处理器进行统一的管理,方便回调。

三、IOC容器注册BeanPostProcessor的源码解析

3.1 IOC容器注册BeanPostProcessor的时序图

在这里插入图片描述

3.2 刷新IOC容器

目标类:AbstractApplicationContext

publicvoidrefresh()throws BeansException, IllegalStateException{synchronized(this.startupShutdownMonitor){...// 调用容器中注册的Bean工厂处理器invokeBeanFactoryPostProcessors(beanFactory);// 注册拦截Bean创建的处理器registerBeanPostProcessors(beanFactory);...// 实例化所有剩余的(非@Lazy)单例。finishBeanFactoryInitialization(beanFactory);...}}

3.3 调用注册LoadTimeWeaverAwareProcessor

目标类:AbstractApplicationContext
目的:注册LoadTimeWeaverAwareProcessor到Spring IOC容器

// 调用容器中注册的Bean工厂处理器protectedvoidinvokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory){
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory,getBeanFactoryPostProcessors());// String LOAD_TIME_WEAVER_BEAN_NAME="loadTimeWeaver"// 注册容器是否包含loadTimeWeaver Bean,如果没有则注册// (如: 通过ConfigurationClassPostProcessor注册的@Bean方法)if(beanFactory.getTempClassLoader()== null&& beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)){// LoadTimeWeaverAwareProcessor实现了BeanPostProcessor接口子类
        beanFactory.addBeanPostProcessor(newLoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(newContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}}

3.4 获取和注册BeanPostProcessor

目标类:PostProcessorRegistrationDelegate

publicstaticvoidregisterBeanPostProcessors(
        ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext){// 根据类型获取BeanPostProcessor的Bean(包含多实例、单实例、以及其他Scope范围的Bean)
    String[] postProcessorNames= beanFactory.getBeanNamesForType(BeanPostProcessor.class,true,false);// 计算BeanPostProcessor数量, 然后创建BeanPostProcessorChecker添加到容器int beanProcessorTargetCount= beanFactory.getBeanPostProcessorCount()+1+ postProcessorNames.length;
    beanFactory.addBeanPostProcessor(newBeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));// 1. priorityOrderedPostProcessors: 实现了PriorityOrdered接口的BeanPostProcessor// 2. internalPostProcessors: 同时实现了PriorityOrdered和MergedBeanDefinitionPostProcessor//    接口的BeanPostProcessor, 也就是Spring内部的BeanPostProcessor// 3. orderedPostProcessorNames: 实现了Ordered接口的BeanPostProcessor// 4. nonOrderedPostProcessorNames: 单纯的BeanPostProcessor// 注意: PriorityOrdered是继承Ordered的接口, 因此处理需要首先判断PriorityOrdered
    List<BeanPostProcessor> priorityOrderedPostProcessors=newArrayList<BeanPostProcessor>();
    List<BeanPostProcessor> internalPostProcessors=newArrayList<BeanPostProcessor>();
    List<String> orderedPostProcessorNames=newArrayList<String>();
    List<String> nonOrderedPostProcessorNames=newArrayList<String>();for(String ppName: postProcessorNames){// 首先处理PriorityOrdered, 因为PriorityOrdered是继承自Ordered的接口if(beanFactory.isTypeMatch(ppName, PriorityOrdered.class)){
            BeanPostProcessor pp= beanFactory.getBean(ppName, BeanPostProcessor.class);
            priorityOrderedPostProcessors.add(pp);if(ppinstanceofMergedBeanDefinitionPostProcessor){
                internalPostProcessors.add(pp);}}elseif(beanFactory.isTypeMatch(ppName, Ordered.class)){
            orderedPostProcessorNames.add(ppName);}else{
            nonOrderedPostProcessorNames.add(ppName);}}// 根据优先级排序priorityOrderedPostProcessorssortPostProcessors(priorityOrderedPostProcessors, beanFactory);// 将priorityOrderedPostProcessors依次注册到beanFactoryregisterBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);// 处理实现Ordered接口的BeanPostProcessor
    List<BeanPostProcessor> orderedPostProcessors=newArrayList<BeanPostProcessor>();for(String ppName: orderedPostProcessorNames){
        BeanPostProcessor pp= beanFactory.getBean(ppName, BeanPostProcessor.class);
        orderedPostProcessors.add(pp);// 如果是Spring内部的BeanPostProcessor,则注册到internalPostProcessorsif(ppinstanceofMergedBeanDefinitionPostProcessor){
            internalPostProcessors.add(pp);}}// 根据优先级排序orderedPostProcessorssortPostProcessors(orderedPostProcessors, beanFactory);// 将orderedPostProcessors依次注册到beanFactoryregisterBeanPostProcessors(beanFactory, orderedPostProcessors);// 处理单纯的BeanPostProcessor
    List<BeanPostProcessor> nonOrderedPostProcessors=newArrayList<BeanPostProcessor>();for(String ppName: nonOrderedPostProcessorNames){
        BeanPostProcessor pp= beanFactory.getBean(ppName, BeanPostProcessor.class);
        nonOrderedPostProcessors.add(pp);// 如果是Spring内部的BeanPostProcessor,则注册到internalPostProcessorsif(ppinstanceofMergedBeanDefinitionPostProcessor){
            internalPostProcessors.add(pp);}}// 无须排序,直接依次注册到beanFactory的末尾registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);// 根据优先级排序internalPostProcessorssortPostProcessors(internalPostProcessors, beanFactory);// 将internalPostProcessors依次注册到beanFactory容器registerBeanPostProcessors(beanFactory, internalPostProcessors);// 总结注册顺序(从尾到头, 因为是逆序调用):// internalPostProcessors > nonOrderedPostProcessors > orderedPostProcessors > priorityOrderedPostProcessors// 重新注册用于检测内部Bean的BeanPostProcessor作为ApplicationListener, 将其移至处理器链的末尾(用于获取代理等)。// 注意:applicationContext为AbstractApplicationContext的实现IOC容器
    beanFactory.addBeanPostProcessor(newApplicationListenerDetector(applicationContext));}

3.5 注册BeanPostProcessor

目标类:PostProcessorRegistrationDelegate
作用:只是把BeanPostProcessor顺序注册到beanFactory容器

privatestaticvoidregisterBeanPostProcessors(
        ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors){for(BeanPostProcessor postProcessor: postProcessors){
        beanFactory.addBeanPostProcessor(postProcessor);}}

3.6 注册BeanPostProcessor到beanFactory

目标类:AbstractBeanFactory

@OverridepublicvoidaddBeanPostProcessor(BeanPostProcessor beanPostProcessor){
    Assert.notNull(beanPostProcessor,"BeanPostProcessor must not be null");// 移除已注册的BeanPostProcessor, 原因是按照新规则排序添加this.beanPostProcessors.remove(beanPostProcessor);this.beanPostProcessors.add(beanPostProcessor);// 判断是否有InstantiationAwareBeanPostProcessor的BeanPostProcessorif(beanPostProcessorinstanceofInstantiationAwareBeanPostProcessor){this.hasInstantiationAwareBeanPostProcessors=true;}// 判断是否存在DestructionAwareBeanPostProcessor的BeanPostProcessorif(beanPostProcessorinstanceofDestructionAwareBeanPostProcessor){this.hasDestructionAwareBeanPostProcessors=true;}}

四、IOC容器调用BeanPostProcessor源码解析

4.1 IOC容器调用BeanPostProcessor的时序图

在这里插入图片描述

4.2 刷新IOC容器

目标类:AbstractApplicationContext

publicvoidrefresh()throws BeansException, IllegalStateException{synchronized(this.startupShutdownMonitor){...// 调用容器中注册的Bean工厂处理器invokeBeanFactoryPostProcessors(beanFactory);// 注册拦截Bean创建的处理器registerBeanPostProcessors(beanFactory);...// 实例化所有剩余的(非@Lazy)单例。finishBeanFactoryInitialization(beanFactory);...}}

4.3 完成BeanFactory的实例化

目标类:AbstractApplicationContext

protectedvoidfinishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory){// String CONVERSION_SERVICE_BEAN_NAME="conversionService"// 判断beanFactory是否存在类型转换服务conversionService, 如果存在则注册到beanFactory// 补充:ConversionService是用于类型转换的服务, 调用convert方法实现类型转换if(beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME)&&
            beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)){
        beanFactory.setConversionService(
                beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));}// 注册Spring SPEL解析器EmbeddedValueResolver// 补充:StringValueResolver为SPEL解析器, 如#{1-1}、${app.port}if(!beanFactory.hasEmbeddedValueResolver()){
        beanFactory.addEmbeddedValueResolver(newStringValueResolver(){@Overridepublic StringresolveStringValue(String strVal){returngetEnvironment().resolvePlaceholders(strVal);}});}// 目的:根据类型获取LoadTimeWeaverAware的Bean, 并且检测LoadTimeWeaverAware是否存在
    String[] weaverAwareNames= beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class,false,false);for(String weaverAwareName: weaverAwareNames){getBean(weaverAwareName);}//  停止使用临时ClassLoader进行类型匹配。
    beanFactory.setTempClassLoader(null);// 缓存Bean定义的元数据
    beanFactory.freezeConfiguration();// 初始化非Lazy的单实例
    beanFactory.preInstantiateSingletons();}

4.4 DefaultListableBeanFactory初始化单实例

目标类:DefaultListableBeanFactory

@OverridepublicvoidpreInstantiateSingletons()throws BeansException{if(this.logger.isDebugEnabled()){this.logger.debug("Pre-instantiating singletons in "+this);}// beanDefinitionNames是配置文件配置的所有Bean名字
    List<String> beanNames=newArrayList<String>(this.beanDefinitionNames);// 触发非Lazy的单实例初始化for(String beanName: beanNames){// 返回Bean的定义
        RootBeanDefinition bd=getMergedLocalBeanDefinition(beanName);// 非抽象类和非Lazy的单实例if(!bd.isAbstract()&& bd.isSingleton()&&!bd.isLazyInit()){// 如果是实现FactoryBean接口定义的Beanif(isFactoryBean(beanName)){// 获取FactoryBean的Bean, 获取方式为:&+Bean名字final FactoryBean<?> factory=(FactoryBean<?>)getBean(FACTORY_BEAN_PREFIX+ beanName);boolean isEagerInit;if(System.getSecurityManager()!= null&& factoryinstanceofSmartFactoryBean){
                    isEagerInit= AccessController.doPrivileged(newPrivilegedAction<Boolean>(){@Overridepublic Booleanrun(){return((SmartFactoryBean<?>) factory).isEagerInit();}},getAccessControlContext());}else{// 判断是否需要立即初始化
                    isEagerInit= factoryinstanceofSmartFactoryBean&&((SmartFactoryBean<?>) factory).isEagerInit();}// 非Lazy单实例if(isEagerInit){getBean(beanName);}}else{getBean(beanName);}}}// 如果Bean实现了SmartInitializingSingleton, 则触发Bean的afterSingletonsInstantiated方法for(String beanName: beanNames){// 获取单实例,如果不是单实例则返回Null
        Object singletonInstance=getSingleton(beanName);if(singletonInstanceinstanceofSmartInitializingSingleton){final SmartInitializingSingleton smartSingleton=(SmartInitializingSingleton) singletonInstance;if(System.getSecurityManager()!= null){
                AccessController.doPrivileged(newPrivilegedAction<Object>(){@Overridepublic Objectrun(){
                        smartSingleton.afterSingletonsInstantiated();return null;}},getAccessControlContext());}else{// 调用单实例的SmartInitializingSingleton处理器
                smartSingleton.afterSingletonsInstantiated();}}}}

4.5 AbstractBeanFactory获取单实例Bean

目标类:AbstractBeanFactory

@Overridepublic ObjectgetBean(String name)throws BeansException{returndoGetBean(name, null, null,false);}// 思路// 1. 如果已缓存类型单实例, 则直接从缓存获取// 2. 如果有集合其他ApplicationContext容器, 试图从继承容器获取, 获取到直接返回// 3. 对Bean进行检查// 4. 依赖项检查, 以及实例化依赖项// 5. 单实例创建// 6. 多实例创建// 7. 其他Scope实例创建// 8. Bean类型检查// 9. 返回创建的实例对象protected<T> TdoGetBean(final String name,final Class<T> requiredType,final Object[] args,boolean typeCheckOnly)throws BeansException{// 返回Bean名称(去除工厂取消引用前缀:&, 并将别名解析为规范名称)final String beanName=transformedBeanName(name);
    Object bean;// singletonObjects     : 单例对象缓存的ConcurrentHashMap// earlySingletonObjects: 早期单例对象缓存的HashMap// 调用结果:// 1. 检查Bean是否已经创建放入到容器中(即singletonObjects), 有则返回// 2. 如果容器中不存在, 则创建单实例Bean加入到earlySingletonObjects// 目的在于解决单实例的循环依赖问题// 补充:后续的AbstractAutowireCapableBeanFactory{@Code doCreateBean}有//      调用removeSingletonIfCreatedForTypeCheckOnly移除
    Object sharedInstance=getSingleton(beanName);if(sharedInstance!= null&& args== null){if(logger.isDebugEnabled()){if(isSingletonCurrentlyInCreation(beanName)){
                logger.debug("Returning eagerly cached instance of singleton bean '"+ beanName+"' that is not fully initialized yet - a consequence of a circular reference");}else{
                logger.debug("Returning cached instance of singleton bean '"+ beanName+"'");}}// 从BeanInstance获取Bean的实例
        bean=getObjectForBeanInstance(sharedInstance, name, beanName, null
  • 作者:we.think
  • 原文链接:https://blog.csdn.net/ioteye/article/details/106596759
    更新时间:2022-10-09 12:55:46