容器扩展点

Spring中容器的扩展点一共有三个地方可以扩展,分别对应于三个接口:BeanPostProcessor,BeanFactoryPostProcessor和FactoryBean

BeanPostProcessor

BeanPostProcessor:这个接口可以使Bean在初始化前面或者后面对Bean实例作出修改,下面来看一个例子,作用是仅仅打出Bean的名字以及信息,首先需要在实现BeanPostProcessor接口:

public class TracingBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("Bean:" + beanName + " ---- " + bean.toString());
        return bean;
    }
}

然后将这个BeanPostProcessor定义到Bean配置信息里面去:

<bean class="com.alibaba.khotyn.test.TracingBeanPostProcessor"/>

这样在容器初始化一个Bean之后,容器就会调用TracingBeanPostProcessor将Bean的信息打印到控制台上。注意这里面配置的BeanPostProcessor甚至没有BeanName。

BeanFactoryPostProcessor

BeanFactoryPostProcessor和前面的BeanPostProcessor在名字上看上去很像,在功能上也是类似的,区别的地方在于BeanFactoryPostProcessor可以对Bean定义信息的元数据进行修改(BeanDefinition),而后者是在Bean初始化的时候可以对Bean实例进行修改,可以说BeanFactoryPostProcessor修改地更为彻底一些。在Spring中,已经有一些类实现了BeanFactoryPostPorcessor来提供一些功能,比如PropertyPlaceholderConfigurer,可以对用Property文件中的属性替换XML文件中的属性,下面是一个简单的例子:

<bean id="beanA" class="com.alibaba.khotyn.test.BeanA">
    <property name="name" value="${name}"></property>
    <property name="address" value="${address}"></property>
</bean>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
         <list>
            <value>configure.properties</value>
         </list>
    </property>
</bean>

这样,Properties中的属性就可以去替换XML中相应的属性了

FactoryBean

这个接口乍看可能不怎么像容器的扩展点。但是考虑到最终的Bean使FactoryBean生产出来,所以Bean的初始化完全掌控在FactoryBean当中,这个接口的确是容器的一个扩展点。