Spring5源码浅析(四)—ConfigurableListableBeanFactory

       在上一篇中,我们简要分析了SingletonRegistry和ConfigurableBeanFactory这两个接口的情况,然后我们知道SingletonRegistry主要是为单例服务的尤其是为那些手动注册的单例来服务的,包含了单例的注册、获取、个数统计,名称返回这几类的函数,并且也知道这个接口里的获取型函数只检查已经被实例化的Bean.另外虽然庞杂,我们也看了ConfigurableBeanFactory,通过研读它的api,我们了解到这个接口主要用于对BeanFactory进行配置包括属性转换,bean的生命周期控制等等,由于这个接口函数比较多,这里就不一一介绍了,大家可以参考《Spring5源码浅析(三)》这篇.

       这篇博文呢,主要来分析一个较为综合的接口—ConfigurableListableBeanFactory,他的情况如下图所示:

 

       由于ConfigurableListableBeanFactory是继承于ListableBeanFactory、ConfigurableBeanFactory、AutowireCapableBeanFactory这三个接口,且前两个接口我们在之前的两篇博文中已经有了较为详细的介绍,因此我们此时先来看一下AutowireCapableBeanFactory这个接口.

       AutowireCapableBeanFactory这个接口是BeanFactory的一个扩展,凡是想具有自动装配能力的factory都会实现这个接口,规定了他们想要给已存在的Bean实例暴露这些功能.这个BeanFactory的子接口并不打算给普通的应用程序代码使用:典型的使用场景请保持使用BeanFactory或ListableBeanFactory.在整合其他框架代码的时候可以利用这个接口来装配和填充那些已存在的且生命周期不受Spring控制的Bean的实例.例如,对于WebWork Actions和Tapestry Page objects尤其有用.值得注意的是,ApplicationContext表面上并没有实现这个接口,因为几乎不会有应用程序代码使用它.那就是说,它也可以通过application context来使用,可以通过(accessible through)ApplicationContext 的ApplicationContext.getAutowireCapableBeanFactory来使用.当然,我们也可以实现BeanFactoryAware接口,这个接口可以获取ApplicationContext甚至是正在运行的ApplicationContext内部的BeanFactory,从而得到AutowireCapableBeanFactory的访问,当然是通过将传入的BeanFactory强制转换成AutowireCapableBeanFactory的方式.

      为了方便我们之后的理解与学习,我们来看一下AutowireCapableBeanFactory的api:

  1. 首先是六个常量:

       AUTOWIRE_NO:该常量表示外部没有定义自动装配的值,注意,此属性不会影响BeanFactoryAware等接口的实现以及通过注解注入时的情况.

       AUTOWIRE_BY_NAME: 该常量表示通过名字来对目标Bean的属性进行装配(适用于Bean所有属性的setter).

       AUTOWIRE_BY_TYPE: 该常量表示通过类型来对目标Bean的属性进行装配(适用于Bean所有属性的setter).

       AUTOWIRE_CONSTRUCTOR: 该常量表示一个贪婪的构造函数会被使用来进行装配(涉及解决一个合适的构造函数)

       AUTOWIRE_AUTODETECT: 这个常量从3.0开始就已经不赞成使用了.如果还在使用这种混合装配策略,为了使装配策略有一个清晰的界线更喜欢基于注解的装配.

        ORIGINAL_INSTANCE_SUFFIX: 当已存在的Bean 实例正在初始化的时候,为”原始实例(original instance)”提供的前缀:追加一个完全限定的bean类名,e.g. “com.mypackage.MyClass.ORIGINAL”,这么追加的目的是为了当没有代理对象的时候仍然可以有给定的实例来返回.

  1.  接着是一组Bean的创建和初始化操作

       createBean(Class<T> beanClass): 完整地创建一个给定类的新的实例.为这个实例执行所有的初始化操作,包括所有可以使用的BeanPostProcessors.注意:这个函数主要用于创建一个新的实例,也会为这个Bean内部的注解字段和方法调用所有标准的bean初始化回调.这并不隐含传统的by-name或by-type类型的属性装配.与createBean(Class,int,Boolean)效果相同.

       createBean(Class<?> beanClass,int autowireMode, boolean dependencyCheck):使用指定的装配策略来为指定的类创建一个新的实例,该接口中所有的常量定义这个函数都支持.该函数会为Bean执行完整的初始化过程,包括所有可以使用的BeanPostProcessors.这是autowire(Class<?> beanClass,int autowireMode,boolean dependencyCheck)所提供的一个有效的超集用来添加initializeBean(Object,String)的行为.

        autowireBean(Object existingBean): 通过应用初始化之后(after-instantiation)的回调以及bean属性的后置处理(post-processing)来对给定Bean内部的属性进行装配(e.g. 注解注入).注意: 这个基本上是为了内部的注解字段和方法,也是为了新实例或反序列化实例而扩展的.这并不隐含传统的by-name或by-type类型的属性装配;可以使用autowireBeanProperties(Object ,int,boolean)来达到这些目的

        configureBean(Object existingBean,String beanName): 配置给定名字的Bean,包括注入Bean的属性,应用Bean的属性值,应用像setBeanName,setBeanFactory这类的factory回调,也会为Bean应用所有的BeanPostProcessors(操作对象包含了那些给定Bean的包装类).很明显这是initializeBean(Object,String)所提供的一个超集,它可以充分地利用相似的Bean来对一个新的Bean的指定属性进行配置.当然,这个方法要求给定的BeanName一定要有一个对应的BeanDefinition.

        autowire(Class<?> beanClass,int autowireMode,boolean dependencyCheck):使用指定的装配策略来为指定的类型实例化一个新的Bean实例.这个函数支持这个接口中所定义的所有常量.为了使实例只应用初始化之前的回调(before-instantiation),也可以设置装配策略为AUTOWIRE_NO.(例如注解驱动的注入).不会应用标准的BeanPostProcessors回调或执行任何对Bean的进一步初始化.这个接口为了达成这些目的提供了有区分的,细粒度的一些操作,比如initializeBean(Object,String).然而,如果有合适的实例构造函数,InstantiationAwareBeanPostProcessor回调会被应用.

        autowireBeanProperties(existingBean,autowireMode,dependencyCheck):通过名字(by-name)或类型(by-type)来为指定的Bean实例装配Bean属性.为了使实例只应用初始化之后的回调(after-instantiation),也可以设置装配策略为AUTOWIRE_NO(应用场景如:注解驱动的注入).和autowire一样,不会应用标准的BeanPostProcessors回调或执行任何对Bean的进一步初始化. 这个接口为了达成这些目的提供了有区分的,细粒度的一些操作,比如initializeBean(Object,String).然而,如果有合适的实例构造函数,InstantiationAwareBeanPostProcessor回调会被应用.

       applyBeanPropertyValues(Object existingBean,String beanName):使用一个给定名字的BeanDefinition的属性值为给定的Bean实例进行实例化操作.beanDefinition可以定义一个完全独立的Bean,然后重复使用它的属性值,也可以将属性值用于已存在的Bean实例.这个方法不会装配Bean的属性;它只是应用了被明显定义的属性值.使用autowireBeanProperties(Object,int,boolean)方法来装配一个已存在的Bean实例.注意,这个方法要求给定的bean名字必须要有一个BeanDefinition.与之前的几个函数类似, 这个函数不会应用标准的BeanPostProcessors回调或执行任何对Bean的进一步初始化. 这个接口为了达成这些目的提供了有区分的,细粒度的一些操作,比如initializeBean(Object,String).然而,如果有合适的实例构造函数,InstantiationAwareBeanPostProcessor回调会被应用.

       initializeBean(Object existingBean,String beanName): 初始化一个给定的原生Bean,为它应用像setBeanName和setBeanFactory一样的工厂回调,也会为它应用所有的BeanPostProcessors(包括了给定原生Bean的包装类).注意:beanFactory中不能存在给定名字的BeanDefinition.将会为传入名字的Bean应用回调,但不会考虑被注册过的bean definition.

        applyBeanPostProcessorsBeforeInitialization(Object existingBean,String beanName):为给定的已存在的Bean实例应用BeanPostProcessor,并调用他们的postProcessBeforeInitialization方法.返回的Bean实例可能是原生Bean的一个包装.

        applyBeanPostProcessorsAfterInitialization(Object existingBean,String beanName):为给定的已存在的Bean实例 应用BeanPostProcessor,并调用他们的postProcessAfterInitialization方法.返回的Bean实例可能是原生Bean的一个包装.

          2. Bean生命周期的控制以及名称和依赖的处理

         destroyBean(Object existingBean): 销毁给定的Bean实例(通常来自于createBean(Class<T>)),并为这个Bean应用DisposableBean接口,这个Bean也会被注册进DestructionAwareBeanPostProcessors.在销毁的过程中所抛出的任何异常都应该被捕获和记录而不是往这个方法的调用者那里抛出.

       resolveNamedBean(Class<?> requiredType): 确定给定的对象类型拥有唯一匹配的对象实例,如果有的话,包括该Bean的名字.实际上这是一个持有匹配实例Bean名称的BeanFactory.getBean(Class)的变量.

       resolveDependency(DependencyDescriptor descriptor,String requestingBeanName)与resolveDependency(DependencyDescriptor,String,Set<String>,TypeConverter): 在Bean在工厂里定义之后解析指定的依赖.

       在了解了AutowireCapableBeanFactory的作用之后,我们就能够发现随着BeanFactory接口层级的不断下移,相关的能力也就从抽象和工厂配置逐渐靠向了具体和实例配置,现在来看一下我们本次分享的主角—ConfigurableListableBeanFactory.大多数的ListableBeanFactory都实现了这个配置型接口.除了ConfigurableBeanFactory之外,它还提供了其他的工具来分析和修改BeanDefinition,还有singleton的预实例化.这个接口和上一个接口一样,都不打算在普通的应用代码中使用:典型的需求还是倾向于使用BeanFactory或者ListableBeanFactory.这个接口只是考虑到了在框架内部需要访问bean factory的配置函数的时候可以达到即插即用的效果.现在我们来具体的看一下这个接口的API:

       ignoreDependencyType(Class<?> type):在装配的时候忽略指定的依赖类型,比如String,默认是无.

ignoreDependencyInterface(Class<?> ifc): 在装配的时候忽略指定的依赖接口.具有代表性的是application context使用这个函数来注册以其他方式解析的依赖,像BeanFactory通过BeanFactoryAware或者ApplicationContext通过ApplicationContextAware.默认的情况下,只有BeanFactoryAware会被忽略.想使更多类型被忽略的话,可以为每一个想要被忽略的类型调用这个函数.

       registerResolvableDependency(Class<?> dependencyType,Object autowiredValue): 注册一个指定的依赖类型并放入可供注入的值.这个函数是给factory/context 引用用的,是为了自动注入那些没有作为Bean被注册在Factory中的那些实体类.例如, Bean内部的ApplicationContext类型的依赖会被解析为一个ApplicationContext实例.注意:在一个扁平的BeanFactory中没用默认的类型被注册,甚至连BeanFactory接口自己都没有.

       isAutowireCandidate():确定一个指定的Bean是否有资格作为自动注入的候选,如果有的话,它将可能会被注入到那些声明了匹配类型依赖的其它Bean中,这个方法也会检查父级的factory.

       getBeanDefinition():返回为指定Bean注册的BeanDefinition,并允许访问他的属性值和构造函数参数值.(这些属性值都可以在beanfactory中的post-processing进行修改) 返回的BeanDefinition对象不是一个拷贝而是在factory中注册过的原生definition对象.这也就意味着如果有必要的话,该对象应该会被转换成一个更具体的实现类型.注意: 这个方法不会考虑祖先级容器.这个方法只是为本地factory中的bean definition来服务的.

       getBeanNamesIterator(): 为所有被这个工厂所管理的Bean的名称返回一个统一的视图.包括bean definition的名字也包括手动注册的单例实例的名字,一贯地是BeanDefinition名字优先.类似于指定类型/注解的bean名字的检索工作.

        clearMetadataCache(): 清理被合并的BeanDefinition缓存,也会移除那些元数据缓存不完整的那些Bean的实体.典型的应用场景是在原生的bean definitions被改变之后触发该函数.例如,在应用了一个BeanFactoryPostProcessor之后.注意:在这一时刻已经被创建的Bean的元数据不受影响.

       freezeConfiguration():冻结所有的BeanDefinition,以及已被注册过的BeanDefinition将不会被修改或任何进一步post-processed的信息.这个函数允许factory侵入性地缓存beanDefinition元数据信息.

       isConfigurationFrozen(): 返回工厂中的beanDefinition是否是被冻结的.i.e. 是否是不应该被修改或进一步post-processed的

       preInstantiateSingleton(): 确保所有non-lazy-init的单例被实例化,也包括FactoryBeans.如果有需求的话,通常是在factory启动的最后调用这个方法.

       截止到目前,我们通过对Spring容器中工厂接口的声明和作用的查看,从而了解到了工厂的基本作用.那这些接口都是如何实现呢?我们从下一次开始,来藉着对DefaultListableBeanFactory等具体工厂接口的实现类的学习,来梳理一下Spring中工厂的实现方式,从而洞悉Spring中的IOC机制.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值