12 BeanFactoryPostProcessor
在上一篇文章中介绍了BeanPostProcessor,我们可以通过自定义BeanPostProcessor实现对实例化以后的bean在调用其初始化方法前后加上特定的逻辑,即所谓的回调。在本文将要介绍的BeanFactoryPostProcessor和上一篇介绍的BeanPostProcessor接口类似,也是属于一个回调接口。所不同的是BeanPostProcessor接口回调对应的主体是bean,其可以在bean实例化以后但是在调用其初始化方法前后进行回调以达到对bean进行处理的效果。而在本文将要介绍的BeanFactoryPostProcessor的主体是BeanFactory,并且该接口中只定义了一个方法,其将会在ApplicationContext内部的BeanFactory加载完bean的定义后,但是在对应的bean实例化之前进行回调。所以通常我们可以通过实现该接口来对实例化之前的bean定义进行修改。
public interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
以上就是BeanFactoryPostProcessor接口的定义,其中只定义了一个方法。接下来我们来定义一个自己的BeanFactoryPostProcessor,用以输出当前bean容器中bean定义的基本信息。
public class HelloBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
public void postProcessBeanFactory(
ConfigurableListableBeanFactory beanFactory) throws BeansException {
//获取所有的beanName
String beanNames[] = beanFactory.getBeanDefinitionNames();
if (beanNames != null && beanNames.length > 0) {
BeanDefinition beanDef = null;
for (String beanName : beanNames) {
//获取对应的bean定义
beanDef = beanFactory.getBeanDefinition(beanName);
this.printBeanDef(beanName, beanDef);
}
}
}
/**
* 打印bean定义的基本信息
* @param beanName
* @param beanDef
*/
private void printBeanDef(String beanName, BeanDefinition beanDef) {
StringBuilder defStr = new StringBuilder("beanName: ").append(beanName);
defStr.append(", className: ").append(beanDef.getBeanClassName());
defStr.append(", scope: ").append(beanDef.getScope());
defStr.append(", parent: ").append(beanDef.getParentName());
defStr.append(", factoryBean: ").append(beanDef.getFactoryBeanName());
defStr.append(", factoryMethod: ").append(beanDef.getFactoryMethodName());
System.out.println(defStr);
}
}
实现了自己的BeanFactoryPostProcessor之后,我们需要把它按照一个普通的bean进行定义的方式将其定义到对应的bean容器中。Spring能够自动检测到定义在bean容器中BeanFactoryPostProcessor对应的bean,并将在所有其它bean定义进行实例化之前对它们进行实例化,之后再回调其中的postProcessBeanFactory()方法。BeanFactoryPostProcessor与之前介绍的BeanPostProcessor类似,也是容器独立的,即一个BeanFactoryPostProcessor只属于单个bean容器,或者换句话说,一个BeanFactoryPostProcessor只能被其所属的那个bean容器进行回调,其所属容器的父容器或子容器都不能对其进行回调。此外,我们也可以在同一个bean容器中同时定义多个BeanFactoryPostProcessor,默认情况下它们的作用顺序将按照定义的先后顺序进行,当BeanFactoryPostProcessor实现了Ordered接口后,作用顺序将按照Ordered接口的getOrder()方法的返回值排列,返回值越小的将越先被回调,实现了Ordered接口的将比没有实现Ordered接口的先被回调。
<bean class="com.app.HelloBeanFactoryPostProcessor"/>
跟BeanPostProcessor一样,Spring将忽略定义在BeanFactoryPostProcessor上的lazy-initialization=”true”
和默认的default-lazy-initialization=”true”
,因为Spring需要保证BeanFactoryPostProcessor的优先实例化。
根据上面内容的介绍我们知道BeanFactoryPostProcessor的主要作用就是在bean实例化之前对bean定义进行修改。其实我们对BeanFactoryPostProcessor并不陌生,其在Spring内部也是用的非常多的。像我们比较熟悉的常用来替换对应变量的PropertyPlaceholderConfigurer、PropertySourcesPlaceholderConfigurer和PropertyOverrideConfigurer其实也是对BeanFactoryPostProcessor的一种实现。
(注:本文是基于Spring4.1.0所写)
相关推荐
Spring注解驱动开发第36讲——或许,这是你以前没看过的从源码角度理解BeanFactoryPostProcessor的原理
com-spring-ioc-demo:源码主要是学习Spring IOC的原理,以及对Bean的注册及控制,主要运用以下类对Spring进行扩展学习:BeanPostProcessor,BeanFactoryAware,BeanNameAware,ApplicationContextAware,FactoryBean...
1 BeanFactoryPostProcessor作用 public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor { /** * 可以修改容器Bean内部的定义信息,全部的bean definitions会加载但是bean没有...
主要介绍了Spring注解驱动扩展原理BeanFactoryPostProcessor,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
3.7.2. 用BeanFactoryPostProcessor定制配置元数据 3.7.2.1. PropertyPlaceholderConfigurer示例 3.7.2.2. PropertyOverrideConfigurer示例 3.7.3. 使用FactoryBean定制实例化逻辑 3.8. ApplicationContext 3.8.1. ...
不使用XML定义档进行 Bean设置 Aware 相关介面 BeanPostProcessor BeanFactoryPostProcessor PropertyPlaceholderConfigurer PropertyOverrideConfigurer CustomEditorConfigurer ...
3.7.2. 用BeanFactoryPostProcessor定制配置元数据 3.7.3. 使用FactoryBean定制实例化逻辑 3.8. ApplicationContext 3.8.1. 利用MessageSource实现国际化 3.8.2. 事件 3.8.3. 底层资源的访问 3.8.4. ...
3.7.2. 用BeanFactoryPostProcessor定制配置元数据 3.7.3. 使用FactoryBean定制实例化逻辑 3.8. The ApplicationContext 3.8.1. BeanFactory 还是 ApplicationContext? 3.8.2. 利用MessageSource实现国际化 ...
《spring开发指南》,欢迎使用spring框架的各位下载。
3.7.2. 用BeanFactoryPostProcessor定制配置元数据 3.7.3. 使用FactoryBean定制实例化逻辑 3.8. ApplicationContext 3.8.1. 利用MessageSource实现国际化 3.8.2. 事件 3.8.3. 底层资源的访问 3.8.4. ...
3.7.2. 用BeanFactoryPostProcessor定制配置元数据 3.7.3. 使用FactoryBean定制实例化逻辑 3.8. The ApplicationContext 3.8.1. BeanFactory 还是 ApplicationContext? 3.8.2. 利用MessageSource实现国际化 ...
了解spring的加载机制 beanPostProcessor,beanFactoryPostProcessor 的使用 springmvc 的父子容器 aop切面说明 公司内部培训课件
4.8.2 使用BeanFactoryPostProcessor 自定义配置元数据. 81 4.8.2.1 示例:PropertyPlaceholderConfigurer. 82 4.8.2.2 示例:PropertyOverrideConfigurer 83 4.8.3 使用FactoryBean 来自定义实例化...
BeanFactoryPostProcessor BeanFactoryReference BeanFactoryRefreshableTargetSource BeanFactoryUtils BeanInitializationException BeanInstantiationException BeanIsAbstractException ...
后置处理器(BeanPostProcessor.BeanFactoryPostProcessor等) 2).监听器(ApplicationListener) 3).Spring容器启动过程; 3).web原理 1).Servlet3.0标准新增特性 2).异步请求相关 本视频使用了maven...
12 Using SLF4J ............................................................................................ 13 Using Log4J ...............................................................................
spring3.1中文参考文档,南磊翻译,现在有4章,目录如下: 第一部分 Spring framework概述.......................................................................................................................
* 所有的bean定义已经保存加载到beanFactory,但是bean的实例还未创建 * * * BeanFactoryPostProcessor原理:
12 Using SLF4J ............................................................................................ 13 Using Log4J ...............................................................................
该项目提供了,如果在Spring 类中遇到以下情况之一,该将发出编译器警告和错误: @Configuration类不能是最终的。 @Configuration类必须具有可见的无参数构造函数。 @Configuration类的构造函数不得为@Autowired...