8.1.3 容器后处理器

8.1.3 容器后处理器

除了上面提供的Bean后处理器, Spring还提供了一种容器后处理器。Bean后处理器负责处理容器中的所有Bean实例,而容器后处理器则负责处理容器本身。
容器后处理器必须实现BeanFactoryPostProcessor接口。实现该接口必须实现如下一个方法。
setProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
实现该方法的方法体就是对Spring容器进行的处理,这种处理可以对Spring容器进行自定义扩展当然也可以对Spring容器不进行任何处理。

postProcessBeanFactory没有返回值

由于开发者不可能完全替换Spring容器(如果完全替換Spring容器,那就没必要使用Spring框架了),因此postProcessBeanFactory方法只是对Spring容器进行后处理,该方法无须任何返回值。
类似于BeanPostProcessorApplicationContext可自动检测到容器中的容器后处理器,并且自动注册容器后处理器。但若使用BeanFactory作为Spring容器,则必须手动调用该容器后处理器来处理BeanFactory容器。

程序示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
E:\workspace_QingLiangJiJavaEEQiYeYingYongShiZhang5\BeanFactoryPostProcessor
└─src\
├─beans.xml
├─lee\
│ └─BeanTest.java
└─org\
└─crazyit\
└─app\
├─service\
│ ├─Axe.java
│ ├─impl\
│ │ ├─Chinese.java
│ │ └─SteelAxe.java
│ └─Person.java
└─util\
└─MyBeanFactoryPostProcessor.java

MyBeanFactoryPostProcessor.java

下面定义了一个容器后处理器,这个容器后处理器实现了BeanFactoryPostProcessor接口,但并未对Spring容器进行任何处理,只是打印出一行简单的信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package org.crazyit.app.util;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor
{
/**
* 重写该方法,对Spring进行后处理。
* @param beanFactory Spring容器本身
*/
public void postProcessBeanFactory(
ConfigurableListableBeanFactory beanFactory) throws BeansException
{
System.out.println("程序对Spring所做的BeanFactory的初始化没有改变...");
System.out.println("Spring容器是:" + beanFactory);
}
}

将容器后处理器作为普通Bean部署在容器中,如果使用ApplicationContext作为容器,容器会自动调用BeanFactoryPostProcessor来处理Spring容器。但如果使用BeanFactory作为Spring容器,则必须手动调用容器后处理器来处理Spring容器。例如如下主程序。

BeanTest.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package lee;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.crazyit.app.service.*;

public class BeanTest
{
public static void main(String[] args)
{
// 以ApplicationContex作为Spring容器
// 它会自动注册容器后处理器、Bean后处理器
@SuppressWarnings("resource")
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"beans.xml");
Person p = (Person) ctx.getBean("chinese");
p.useAxe();
}
}

上面程序中代码使用了ApplicationContext作为Spring容器, Spring容器会自动检测容器中的所有Bean,如果发现某个Bean类实现了BeanFactoryPostProcessor接口, ApplicationContext会自动将其注册为容器后处理器。
Spring没有提供ApplicationContextPostProcessor。也就是说,对于ApplicationContext容器,一样使用BeanFactoryPostProcessor作为容器后处理器。

Spring常用的后处理器

Spring已提供如下几个常用的容器后处理器。

后处理器 描述
PropertyPlaceholderConfigurer 属性占位符配置器
PropertyOverrideConfigurer 重写占位符配置器。
CustomAutowireConfigurer 自定义自动装配的配置器。
CustomScopeConfigurer 自定义作用域的配置器。

从上面的介绍可以看出,容器后处理器通常用于对Spring容器进行处理,并且总是在容器实例化任何其他的Bean之前,读取配置文件的元数据,并有可能修改这些元数据
如果有需要,程序可以配置多个容器后处理器,多个容器后处理器可设置order属性来控制容器后处理器的执行次序。
为了给容器后处理器指定order属性,则要求容器后处理器必须实现Ordered接口,因此在实现BeanFactoryPostProcessor时,就应当考虑实现Ordered接口。

容器后处理器的作用域是容器级的

容器后处理器的作用域范围是容器级,它只对容器本身进行处理,而不对容器中的Bean进行处理;如果需要对容器中的Bean实例进行后处理,则应该考虑使用Bean后处理器,而不是使用容器后处理。