目录
1.通过使用BeanPostProcessor定制beans
2.通过使用BeanFactoryPostProcessor定制配置元数据
容器扩展点
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实例。