试读Spring源码(三)根据Class获取Bean----getBean(Class<T> requiredType)

根据给定类型,获取Bean的具体实现是在DefaultListableBeanFactory类下的<T> T getBean(Class<T> requiredType) throws BeansException方法。其具体实现叙述如下。

调用resolveBean方法,该方法调用resolveNamedBean方法获取到封装了该类型Bean的NamedBeanHolder,如果获取为空,则调用其父BeanFactory获取Bean。

进入resolveNamedBean方法,该方法在首先获取所有类型为指定Class类型的Bean Name。如果获取的Bean Name 数量刚好为1一个,则创建一个NamedBeanHolder,包含该Bean Name和Bean实例,然后返回。如果获取的数量大于1,先实例化所有获取到的Bean,然后通过determinePrimaryCandidate 方法获取属性primary为true的Bean,如果有多个Bean的primary的属性为true,则抛出异常。如果不存在任何一个Bean的primary为true,则通过OrderComparator 比较器来获取Bean的优先级,如果存在多个Bean优先级相同,也抛出异常。

从getBean进入到doGetBean方法,该方法是从BeanFactory创建或者返回已存在Bean的实例。首先通过transformedBeanName方法获取Bean Id。从这个方法上看,Spring应该是允许为别名取别名。获取到Bean Id后先判断是否已存在创建好的单例。如果不存在创建好的单例,且BeanFactory不包含该Bean Id的BeanDefinition,且存在父BeanFactory,则调用父BeanFactory的getBean方法获取Bean。当不符合上述条件,则开始创建Bean的实例。

创建Bean的实例时,先通过getMergedLocalBeanDefinition获取到RootBeanDefinition。合并BeanDefinition是前面初始化时加载好的BeanDefinition中复制一份。如果Bean存在parent definition,就根据parent definition创建一个实例,然后覆盖。当有子孙链的时候将递归调用。获取到BeanDefinition后,根据获取到的BeanDefinition取到该Bean的依赖dependsOn,在将依赖关系注册到BeanFactory后,同样采用递归调用getBean方式获取依赖Bean。接下来判断Bean是否为单例,将采用不同的实例化方法。

当Bean为单例时,会调用getSingleton方法,来获取Bean实例。该方法先判断单例是否存在,如不存在,则开始创建该单例,先做准备工作,将其添加到singletonsCurrentlyInCreation,表示该单例正在创建,避免重复创建,然后调用ObjectFactory的getObject方法,将实例的实现移交给ObjectFactory接口,方便扩展。获取到单例后,将其移除singletonsCurrentlyInCreation,然后将其添加到singletonObjects和registeredSingletons中。

进入创建单例的ObjectFactory实现方法createBean。该方法实现了一个单例创建的完整过程,包括解决单例所属类的加载,单例的实例化,单例属性的赋值或者注入,以及在Spring中创建的生命周期相关的接口的调用。首先通过resolveBeanClass方法加载单例的类对象,并将其设置到BeanDefinition中。然后调用resolveBeforeInstantiation方法,这个方法按照注释,是说给BeanPostProcessors一个机会返回一个代理对象,进到方法里可以看到,如果存在InstantiationAwareBeanPostProcessor处理器,且能够实现对需要获取的Bean实例化,则对该处理器返回的对象调用已注册在BeanFactory的后置处理器,然后就返回,不再对该Bean做其他的处理,也就是将Bean的实例,完全交给了用户自定义的处理器。在没有返回代理对象时,Spring将通过doCreateBean对Bean做实例化。

doCreateBean实例化时,首先通过createBeanInstance方法,采用策略模式,生成包含实例Bean的BeanWrapper实例。其中包含的策略,就是在配置文件配置的生成实例的方式,如工厂方法factory method,构造器constructor autowiring, 或者是其他简单的实例化(没有配置factory-method,也没有配置构造器)。接下来,如果定义有MergedBeanDefinitionPostProcessor处理器,这个节点将会调用。然后在对Bean定义的属性进行计算之前,还将调用InstantiationAwareBeanPostProcessor处理器来对Bean进行处理,这里注释是可用于支持属性注入的方式,这个没懂。后面就是对Bean属性的计算,然后将其设置到Bean实例中。

执行initializeBean方法,处理Bean在Spring的生命周期。这里判断Bean是否实现了相应的事件接口,如BeanNameAware,BeanClassLoaderAware,BeanFactoryAware,这里会调用并注入相应的对象。然后对Bean调用已注册的BeanPostProcessor的postProcessBeforeInitialization方法。执行完后将执行配置里的init方法,如果Bean还实现了InitializingBean接口,这里还将先执行接口里的afterPropertiesSet方法。这样,Bean在Spring的一个创建周期就走完了。

当Bean为多例时,调用过程也类似,就不再赘述。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值