AbstractBeanFactory.getBean获取bean逻辑(二)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hjtlovelife/article/details/90265949

AbstractBeanFactory.getBean获取bean逻辑(一)

6、标记要创建的bean为已创建或即将创建

        如果创建bean不仅仅类型检查,调用AbstractBeanFactory.markBeanAsCreated方法将指定的bean标记为已创建(或即将创建),这允许bean工厂优化其缓存的beanDefinition以重复创建指定的bean。

       如果bean没有创建过清除AbstractBeanFactory.mergedBeanDefinitions中已经存在的合并beanDefinition,让beanDefinition重新合并,因为我们实际上正在创建bean,以防万一其中的一些元数据在此期间发生了变化。

        bean创建失败时才会从AbstractBeanFactory.alreadyCreated移除。

        AbstractBeanFactory.mergedBeanDefinitions有多个入口调用往AbstractBeanFactory.mergedBeanDefinitions中放入beanDefinition。

7、将存储XML配置文件的GernericBeanDefinition转换为RootBeanDefinition
        返回合并的RootBeanDefinition,如果指定的bean有父beanDefinition,则遍历父beanDefinition。AbstractBeanFactory.
getMergedLocalBeanDefinition调用AbstractBeanFactory.getMergedBeanDefinition方法生成合并beanDefinition。如果没有父beanDefinition且允许缓存bean元数据则会放入到AbstractBeanFactory.mergedBeanDefinitions中暂时缓存合并beanDefinition(稍后可能仍会重新合并以获取元数据更改)。

        如果parentName为null直接生成RootBeanDefinition,否则如果beanName和parentName相同则会从父容器中查找,若不存在父容器则会抛异常。没有指定scope默认是单例,若有父bean则使用父bean的scope配置。如果没有父beanDefinition且允许缓存bean元数据则会放入到AbstractBeanFactory.mergedBeanDefinitions中暂时缓存合并beanDefinition(稍后可能仍会重新合并以获取元数据更改)。

扫描二维码关注公众号,回复: 6426319 查看本文章

8、寻找依赖bean并保证当前bean依赖的bean的初始化

        因为bean初始化过程中很可能会用到某些属性,而某些属性很可能是动态配置的,并且配置成依赖于其他的bean,那么这个时候就有必要先加载依赖的bean,所以在Spring的加载顺寻中,在初始化某一个bean的时候首先会初始化这个bean所对应的依赖。

9、针对不同的scope进行bean的创建

        在Spring 中存在着不同的scope,其中默认的是singleton, 但是还有些其他的配置诸如prototype、request 、session等。在这个步骤中, Spring会根据不同的配置进行不同的初始化策略。以单例bean创建为例,调用DefaultSingletonBeanRegistry.getSingleton方法获取单例实例。

DefaultSingletonBeanRegistry.getSingleton方法处理逻辑如下:
(1) 检查缓存是否已经加载过,若已经加载过直接返回实例。
(2) 若没有加载,则记录beanName为正在加载状态。
(3) 通过调用参数传人的ObjectFactory.getObject方法实例化bean。如果抛异常单例对象是否在此期间隐式出现如果是,则继续执行,因为异常表示该状态。
(4) 加载单例后的处理方法调用。
(5) 如果是新创建的单例实例将结果记录到缓存并删除加载bean过程中所记录的各种辅助状态。
        ObjectFactory.getObject方法其实调用AbstractAutowireCapableBeanFactory.createBean方法(prototype bean实例创建也是调用该方法)创建bean。

        单例实例添加到Spring容器单例池中,获取单例实例后调用DefaultSingletonBeanRegistry.addSingleton方法添加到spring容器单例池中。

        可以直接调用DefaultSingletonBeanRegistry.registerSingleton方法注册单例实例到spring容器单例池中,最终调用DefaultSingletonBeanRegistry.addSingleton方法。

        ObjectFactory.getObject获取bean实例方法其实调用AbstractAutowireCapableBeanFactory.createBean方法(prototype bean实例创建也是调用该方法)创建bean。

创建bean流程如下:

(1) 确保此时实际解析了bean类,并在动态解析的Class的情况下克隆bean定义,该类无法存储在共享的合并bean定义中。

(2) 验证并准备为此bean定义的覆盖方法,检查是否存在具有指定名称的方法,如果没有找到则将其标记为未重载,以避免arg类型检查的开销。

        对于方法的匹配来讲,如果一个类中存在若干个重载方法,在函数调用及增强的时候还需要根据参数类型进行匹配,来最终确认当前调用的到底是哪个函数。但是,Spring将一部分匹配工作在这里完成了,如果当前类中的方法只有一个,那么就设置重载该方法没有被重载,这样在后续调用的时候便可以直接使用找到的方法,而不需要进行方法的参数匹配验证了,而且还可以提前对方法存在性进行验证。

        MethodOverrides.getOverride调用LookupOverride、ReplaceOverride中matches方法获取最后一个匹配的LookupOverride、ReplaceOverride。CglibSubclassingInstantiationStrategy实例化策略会使用MethodOverrideCallbackFilter回调过滤方法拦截行为。

(3) 为BeanPostProcessors提供返回代理而不是目标bean实例的机会。

        将InstantiationAwareBeanPostProcessors应用于指定的bean定义(按类和名称),调用它们的{@code postProcessBeforeInstantiation}方法。任何返回的对象都将用作bean,而不是实际实例化目标bean。来自后处理器的{@code null}返回值将导致目标bean被实例化。

        Spring中的规则是在bean的初始化后尽可能保证将注册的后处理器的postProcessAfterInitialization方法应用到该bean中,因为如果返回的bean不为空,那么便不会再次经历普通bean的创建过程,所以只能在这里应用后处理器postProcessAfterInitialization方法。

(4) 创建bean

调用AbstractAutowireCapableBeanFactory.doCreateBean方法完成bean的创建

进入AbstractAutowireCapableBeanFactory.doCreateBean方法创建bean实例流程如下:

(4.1) 根据指定bean使用对应的策略创建新的实例,如:工厂方法、构造函数自动注人、简单初始化


(4.2) 允许后处理器修改合并的BeanDefinition,比如InitDestroyAnnotationBeanPostProcessor会提取初始化、销毁方法。

(4.3) 即使在像BeanFactoryAware这样的生命周期接口触发时,也需要早起缓存的单例以便能够解析循环引用

(4.4) 对bean进行填充,将各个属性值注人其中,可能存在依赖于其他bean的属性,则会递归初始化。初始化给定的bean实例,应用工厂回调以及init方法和bean后处理器。对于传统定义的bean,从{@link #createBean}调用,对于现有的bean实例,从{@link #initializeBean}调用。

(4.5) 因为bean创建后其所依赖的bean一定是已经创建的,actualDependentBeans不为空则表示当前bean创建后其依赖的bean却没有没全部创建完,也就是说存在循环依赖。

(4.6) 将给定的bean添加到此工厂中的一次性Bean列表中,注册其DisposableBean接口和/或在工厂关闭时调用的给定destroy方法(如果适用),仅适用于单例。

10、类型转换
        检查所需类型是否与实际bean实例的类型匹配,通常对该方法的调用参数requiredType是为空的,但是可能会存在这样的情况,返回的bean其实是String, 但是requiredType 却传入Integer类型,那么这时候本步骤就会起作用了,它的功能是将返回的bean转换为requiredType所指定的类型。String 转换为Integer是最简单的一种转换,Spring中提供了各种各样的转换器,用户也可以自定义扩展转换器来满足需求。

猜你喜欢

转载自blog.csdn.net/hjtlovelife/article/details/90265949