b spring之扩展ioc机制

–> go to 总目录

8 Container Extesion Points

容器扩展点

通常,应用程序开发人员不需要为ApplicationContext实现类提供子类。相反,可以通过插入特殊集成接口的实现来扩展Spring IoC容器。接下来的几节描述了这些集成接口。

8.1 利用BeanPostProcessor自定义Bean

BeanPostProcessor接口定义了回调方法,您可以实施这些回调方法以提供自己的(或覆盖容器的默认值)实例化逻辑,依赖关系解析逻辑等。
如果您想在Spring容器完成实例化,配置和初始化bean之后实现一些自定义逻辑,则可以插入一个或多个自定义BeanPostProcessor实现。

您可以配置多个BeanPostProcessor实例,并且可以通过设置order属性来控制这些BeanPostProcessor实例的执行顺序。
仅当BeanPostProcessor实现Ordered接口时,才可以设置此属性。如果您编写自己的BeanPostProcessor,则也应该考虑实现Ordered接口。有关更多详细信息,请参见BeanPostProcessor和Ordered接口的javadoc。

! BeanPostProcessor实例在bean(或对象)实例上运行。也就是说,Spring IoC容器实例化一个bean实例,然后BeanPostProcessor实例完成其工作。
BeanPostProcessor实例是按容器划分作用域的。仅在使用容器层次结构时,这才有意义。如果在一个容器中定义BeanPostProcessor,它将仅对该容器中的bean进行后处理。换句话说,一个容器中定义的Bean不会被另一个容器中定义的BeanPostProcessor进行后处理,即使这两个容器是同一层次结构的一部分。
要更改实际的bean定义(即定义bean的蓝图),您需要使用BeanFactoryPostProcessor,如使用BeanFactoryPostProcessor自定义配置元数据中所述。

org.springframework.beans.factory.config.BeanPostProcessor接口恰好由两个回调方法组成。当此类被注册为容器的后处理器(post-processor )时,对于容器创建的每个bean实例,后处理器都会在容器初始化方法(如InitializingBean.afterPropertiesSet()或任何声明的init方法),并在任何bean初始化回调之后调用。后处理器可以对bean实例执行任何操作,包括完全忽略回调。 Bean后处理器通常检查回调接口,或者可以用代理包装Bean。一些Spring AOP基础结构类被实现为bean后处理器,以提供代理包装逻辑。

ApplicationContext自动检测实现BeanPostProcessor接口的配置元数据中定义的所有bean。 ApplicationContext将这些bean注册为后处理器,以便以后在bean创建时可以调用它们。 Bean后处理器可以与其他Bean相同的方式部署在容器中。

注意,在配置类上使用@Bean工厂方法声明BeanPostProcessor时,工厂方法的返回类型应该是实现类本身,或者至少是org.springframework.beans.factory.config.BeanPostProcessor接口。指示该bean的后处理器性质。否则,ApplicationContext无法在完全创建之前按类型自动检测它。由于BeanPostProcessor需要及早实例化才能应用于上下文中其他bean的初始化,因此这种早期类型检测至关重要。用来做其他bean的回调函数,所以要更早的初始化

编程化的注册 BeanPostProcessor 实例
当使用BeanPostProcessor的方式是通过向ApplicationContext的自动检测注册时,针对ConfigurableBeanFactory可以使用addBeanPostProcess方法完成注册。这个是有用的,当你需要针对不同逻辑条件或者在层级化的copy BeanPostProcessor
注意BeanPostProcessor 实例的编程式添加不能代表Ordered
接口。这里有注册信息描述执行的顺序。
注意BeanPostProcessor的注册总是在 这些动作之前通过auto-detcion,无视任何严格的顺序。

BeanPostProcessor实例 和AOP-proxying
BeanPostProcessor实例和AOP自动代理
实现BeanPostProcessor接口的类是特殊的,并且容器对它们的处理方式有所不同。作为ApplicationContext特殊启动阶段的一部分,在启动时会实例化它们直接引用的所有BeanPostProcessor实例和Bean。接下来,以排序方式注册所有BeanPostProcessor实例,并将其应用于容器中的所有其他bean。因为AOP自动代理是作为BeanPostProcessor本身实现的,所以BeanPostProcessor实例或它们直接引用的bean都没有资格进行自动代理,因此没有编织的方面。
对于任何此类bean,您应该看到一条参考性日志消息:Bean someBean不适合所有BeanPostProcessor接口进行处理(例如:不适合自动代理)。
如果您使用自动装配或@Resource(可能会退回到自动装配)将Bean连接到BeanPostProcessor中,则Spring在搜索类型匹配的依赖项候选对象时可能会访问意外的Bean,因此使它们不符合自动代理或其他种类的条件。例如,如果您有一个以@Resource注释的依赖项,其中字段或设置器名称不直接与bean的声明名称相对应,并且不使用name属性,那么Spring将访问其他bean以按类型匹配它们

示例:基础的调用toString方法

第一个例子是基础的应用,这个示例展示如何自定义BeanPostProcessor 实现(侵入调用每个bean方法的toString()),在容器启动的时候然后打印到控制台。
在这里插入图片描述
xml配置
在这里插入图片描述
注意为什么Processor仅仅只有一个定义,连名字也没有。因为他们是一个bean,可以自动被注入到其他bean当做依赖。
运行
在这里插入图片描述
输出
在这里插入图片描述

示例:注解式的Proccess

使用callback接口类或者注解来添加一个自定义的BeanPostProcessor实现是最常用的做法。
RequiredAnnotationBeanPostProcessorBeanPostProcessor的实现确保Bean的属性(可以被任意的注解标记)是真实的注入了一个值,而非空。
就是属性检查的Proccessor

8.2 使用BeanFactoryPostProcessor自定义Custommizing Configuration Metadata

异同
BeanFctoryProcessor和PostProcessor语义类型。主要区别是:BeanFctoryProcessor在bean的Configuration Metadata级别操作。因此Spring利用它在加载bean之前,通过修改configruation meataData的方式来实现接入。

使用要点
可以定义多个BeanFctoryProcessor,可以通过order属性,指定
BeanFctoryProcessor实例的执行顺序。但是只能是在BeanFctoryProcessor实现Ordered接口的前提下。

注意:
如果你想你想要改真实的bean实例,请使用 BeanPostProcessor。如果强行使用BeanFactoryPostProcessor去修改bean的实例(如BeanFactory.getBean() )会造成bean的过早实例化,发生错误。
所以BeanFactoryPostProcessor的sope是 per-container–在容器之前。同时BeanFactoryPostProcessor只会在你定义的contanier生效

行为描述
BeanFactoryPostProcessor在 ApplicationContext中声明后,会自动被执行。除了自定义外,Spring本身包含了很多BeanFactoryPostProcessor,例如PropertyOverrideConfigurerPropertySourcesPlaceholderConfigurer

示例:class 名称的替换–PropertySourcesPlaceholderConfigurer

PropertySourcesPlaceholderConfigurer可以把bean的properties信息以Properties格式放到单独的文件。这样就可以根据不同环境,人为的更改属性的变量–比如database,url,和密码–无需修改xml文件。
配置属性文件
在这里插入图片描述
jsp的EL表达式${jdbc.url}这些变量信息在
java Properties文件格式的文件下
变量文件
在这里插入图片描述
作用
PropertySourcesPlaceholderConfigurer做多是被使用来做检查变量是否合发,单也可以更改变量:比如加前缀后缀。
使用<context>标签,来指明jdbc.properties文件位置。
在这里插入图片描述
如果placeHolder找不到的话,就从Environment属性和System properties属性找

属性名替换:关注properties
在这里插入图片描述
运行中如果找不到相关类就会报失败

示例2:PropertyOverrideConfigurer

PropertyOverrideConfigurer会覆盖原始bean属性的相同字段。PropertyOverrideConfigurer需要的配置文件也是Properties格式。
使用context:property-override
在这里插入图片描述

8.3 使用FactoryBean 自定义实例的逻辑

也可以实现org.springframework.beans.factory.FactoryBean接口来工作。
FactoryBean接口是Spring IoC容器实例化的一个接入点。如果你有复杂的初始化逻辑,可以是用他。
内部方法
FactoryBean接口的三个方法

  • Object getObject(): 返回示例对象
  • boolean isSingleton(): 判断是否singleTon
  • Class getObjectType(): 返回getObject()返回类的对象类型

FactoryBean 概念和接口被 Spring Framework大量使用. Spring Framework有超过50个方法。
使用注意
当你需要从容器获取一个真实的FactoryBean的实例自身时,而不是他提供的。
请在 bean的 id 前加 '&'如getBean("&myBean")。获取它提供的就是getBean("myBean")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值