–> go to 总目录

文章目录

  • 8 Container Extesion Points
    • 8.1 利用BeanPostProcessor自定义Bean
      • 示例:基础的调用toString方法
      • 示例:注解式的Proccess
    • 8.2 使用BeanFactoryPostProcessor自定义Custommizing Configuration Metadata
      • 示例:class 名称的替换--PropertySourcesPlaceholderConfigurer
      • 示例2:PropertyOverrideConfigurer
    • 8.3 使用FactoryBean 自定义实例的逻辑

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")

b spring之扩展ioc机制相关推荐

  1. spring的DI/IOC机制

    先就IOC和DI谈一点我的看法. IOC(DI):其实这个Spring架构核心的概念没有这么复杂,更不像有些书上描述的那样晦涩.Java程序员都知道:java程序中的每个业务逻辑至少需要两个或以上的对 ...

  2. 说说你对Spring的IOC机制的理解可以吗?

    如果没有springIOC的情况下,写一套系统:Tomcat+Servlet  其中调用impl的时候,通过new来创建对象(程序主动创建依赖) 每次都需要new一个,导致耦合度太高,如果后期变动.更 ...

  3. Spring Boot 扩展点应用之工厂加载机制

    Spring 工厂加载机制,即 Spring Factories Loader,核心逻辑是使用 SpringFactoriesLoader 加载由用户实现的类,并配置在约定好的META-INF/spr ...

  4. Java面试必问!Spring事务扩展机制(2)

    TransactionAspectSupport#invokeWithinTransaction TransactionAspectSupport#invokeWithinTransaction 是 ...

  5. 《Spring揭秘》——IOC梳理2(容器启动,bean生命周期)

    IoC容器背后的秘密 主要分为两个阶段:容器启动阶段.Bean实例化阶段. 容器启动阶段: 容器需要依赖某些工具类(BeanDefinitionReader)对加载的Configuration Met ...

  6. spring源码分析第二天------spring系统概述以及IOC实现原理

    1.Spring5 概述 Spring 是一个开源的轻量级 Java SE(Java 标准版本)/Java EE(Java 企业版本)开发应用框架, 其目的是用于简化企业级应用程序开发. Spring ...

  7. 一步一步手绘Spring IOC运行时序图一(Spring 核心容器 IOC初始化过程)

    相关内容: 架构师系列内容:架构师学习笔记(持续更新) 一步一步手绘Spring IOC运行时序图一(Spring 核心容器 IOC初始化过程) 一步一步手绘Spring IOC运行时序图二(基于XM ...

  8. Spring中的IOC介绍

    Spring中的IOC介绍 IOC(控制反转) IOC介绍 IOC是什么 IOC能做什么 Spring容器管理对象 1.maven管理依赖 2.给定容器的配置文件 3.IOC容器管理对象 4.通过容器 ...

  9. Spring Framework Core IOC

    Core IoC Container 依赖注入的方式如下: 通过构造函数参数 通过工厂方法的参数 从构造或者工厂方法返回的对象实例上设置的属性 这个过程通过直接使用类的构造或者类似服务定位器模式的机制 ...

最新文章

  1. 算法----- 在排序数组中查找元素的第一个和最后一个位置
  2. Linux 下复制(cp)目录时排除一个或者多个目录的方法
  3. 【类库】私房干货.Net数据层方法的封装
  4. C++学习笔记:(三)静态与名字空间
  5. Unsafe使用技巧之数组操作
  6. #{} vs ${}
  7. 小程序根据手机机型设置自定义底部导航距离
  8. C语言宏的特殊用法和几个坑 (转)
  9. C-求二元一次方程解
  10. Shaolin(map||set)
  11. postgreSql连接报不支持10验证类型
  12. 美国弗吉尼亚大学计算机科学,弗吉尼亚大学计算机科学专业排名第30(2020年USNEWS美国排名)...
  13. 红米note3android5.0,小米红米note3MOSBeta5.0安卓8.1.0来去电归属农历等本地化增强适配...
  14. ui设计需要做android和苹果版本,安卓和IOS系统对于UI设计来说一样吗
  15. 2011年国外最受欢迎的15个汽车网站
  16. 【那些年我们一起看过的论文】之《ENet: A Deep Neural Network Architecture for Real-Time Semantic Segmentation》
  17. WordPress 元老 Alex King 逝世
  18. python中title函数有什么用_Python title()字符串处理函数的使用
  19. Kaldi单音子建模
  20. 程序员如何用技术变现?

热门文章

  1. 浅谈外汇EA,如何让交易更安全?
  2. 字节,比特,字符,位,单位换算
  3. 放弃高薪回家种韭菜,他赚了30万元
  4. 助手论坛斑竹一些胡言乱语
  5. java floor cell_英语翻译The cell floor and its composite liner system was sloped
  6. 求e的近似值 (15 分)
  7. 互联网公司实习岗位选择与简易版职业发展规划
  8. 【java后端学习】java语言基础(夯实基础)
  9. ❤送女朋友生日快乐祝福网页制作❤(HTML+CSS+JS)
  10. 关于win10笔记本电脑设置账号密码,但是关闭盖子打开后不进入输入密码界面的解决方法