IoC容器篇(七)——容器扩展点

容器扩展点

Spring IoC容器可以通过插入特定接口的实现来扩展功能。因此,无需通过继承ApplicationContext的方式来扩展容器功能。

1.通过使用BeanPostProcessor定制beans

通过实现BeanPostProcessor接口定义的回调方法,开发者可以重载容器默认的初始化逻辑与依赖处理逻辑等。

可以通过插入一个或多个BeanPostProcessor的实现,定义在Spring容器结束初始化、配置以及初始化bean之后的一些自定义逻辑。

BeanPostProcessor用于改变根据配置元数据创建的bean实例。

package examples;

import org.springframework.beans.factory.config.BeanPostProcessor;

public class ExampleBeanPostProcessor implements BeanPostProcessor {

    // simply return the instantiated bean as-is
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        return bean; // we could potentially return any object reference here...
    }

    public Object postProcessAfterInitialization(Object bean, String beanName) {
        System.out.println("Bean '" + beanName + "' created : " + bean.toString());
        return bean;
    }
}
<bean class="examples.ExampleBeanPostProcessor" />

note:定义一个名为ExampleBeanPostProcessor的post-processor,并通过基于xml的方式注册。

ps:BeanPostProcessor由两个回调方法构成。容器初始化方法被调用之前以及任何bean初始化方法调用之后都会引起post-processor的回调。

ps:如果多个BeanPostProcessor实例同时实现BeanPostProcessor接口与Ordered接口,这样可以通过设置这些实例的order属性来设置这些实例的执行顺序。

ps:BeanPostProcessor操作bean,所以,IoC实例化bean之后开始执行BeanPostProcessor。

ps:BeanPostProcessor是容器范围的,即配置在单个容器之中。

ps:post-processor可以如同任何其他beans一样配置在容器中。

ps:使用回掉接口或注解与定制的的BeanPostProcessor实现一起使用是一种扩展Spring IoC容器的常用手段。

ps:RequiredAnnotationBeanPostProcessor就是Spring IoC内置实现。

通过ConfigurableBeanFactory的addBeanPostProcessor方法可以编程方式注册BeanPostProcessor。

编程方式注册的BeanPostProcessor不遵守Ordered接口,注册的顺序就是执行的顺序。编程方式注册的BeanPostProcessor要比自动检测注册的要早执行,除非显式指定顺序。

所有实现BeanPostProcessor的类以及它们引用的beans都会在startup阶段直接被初始化,作为ApplicationContext的startup阶段的一部分。

由于AOP自动代理通过BeanPostProcessor实现,所以BeanPostProcessor以及它们直接引用的bean不能被自动代理,因此,不要将切面编入这些bean。
 

2.通过使用BeanFactoryPostProcessor定制配置元数据

IoC容器允许BeanFactoryPostProcessor在容器初始化其他任何beans之前读取并修改配置元数据。

如果多个BeanFactoryPostProcessor实例同时实现BeanPostProcessor接口与Ordered接口,这样可以通过设置这些实例的order属性来设置这些实例的执行顺序。

BeanFactoryProcessor可以通过BeanFactory.getBean()获取bean实例用来进行操作,但是这样做会获取一个不成熟bean实例,并且可能绕过bean post processing。

BeanPostProcessor是容器范围的,即配置在单个容器之中。

声明在ApplicationContext中的 bean factory post-processor会被自动执行。

即使在beans元素中配置default-lazy-init属性为false,Bean(Factory)PostFactory也不会怠惰初始化,而是尽可能早的初始化。

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations" value="classpath:com/foo/jdbc.properties"/>
</bean>

<bean id="dataSource" destroy-method="close"
        class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="${jdbc.driverClassName}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>

note:配置PropertyPlaceholderConfigurer。

3.通过使用FactoryBean定制初始化逻辑

org.springframework.beans.factory.FactoryBean接口的的实现产生的对象,其本身就是工厂。

FactoryBean接口是Spring IoC容器初始化逻辑的插入点。

FactoryBean提供了三个方法:

Object getObject():返回一个此工厂创建的实例。

boolean isSingleton():如果FactoryBean返回的对象为单例,返回true。

Class getObjectType():返回getObject()方法返回的对象的类型,如果此类型无法预先得知,返回null。

getBean("&example");

note:获取产生id为example的bean的BeanFacotry实例。

学习源:Spring官方文档

猜你喜欢

转载自blog.csdn.net/qq_32165041/article/details/82498991