refresh() ->postProcessBeanFactory()
子类覆盖方法做额外的处理
//在标准初始化后修改应用程序上下文的内部bean工厂。所有的bean定义都将被加载,但是还没有bean被实例化。这允许在某些ApplicationContext实现中注册特殊的BeanPostProcessors等
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { }
由prepareBeanFactory()方法可知,beanFactory可注册BeanPostProcessor,所以该方法可以重写注册自定义的BeanPostProcessor
package com.armin.self_aware;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyClassPathApplicationContext extends ClassPathXmlApplicationContext {
public MyClassPathApplicationContext(String... configLocations) throws BeansException {
super(configLocations);
}
@Override
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
setAllowBeanDefinitionOverriding(false);
setAllowCircularReferences(false);
super.customizeBeanFactory(beanFactory);
}
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
System.out.println("扩展实现postProcessBeanFactory,添加自定义BeanPostProcessor");
beanFactory.addBeanPostProcessor(new MyAwareProcessor(this));
}
}
除了重写postProcessBeanFactory方法进行BeanPostProcesor的注入外还可以使用xml配置的形式进行注入
<bean class="com.armin.self_aware.MyAwareProcessor"/>
这里使用的是无参构造
自定义的BeanPostProcessor
package com.armin.self_aware;
import com.armin.self_editor.Address;
import com.armin.self_editor.Customer;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ConfigurableApplicationContext;
public class MyAwareProcessor implements BeanPostProcessor {
private final ConfigurableApplicationContext applicationContext;
public MyAwareProcessor(ConfigurableApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("前置执行bean增强!");
//增强Customer bean的信息
if (bean instanceof Customer) {
Customer customer = (Customer) bean;
customer.setAddress(new Address("四川省", "眉山市", "东坡区"));
customer.setApplicationContext(this.applicationContext);
}
return bean;
}
}
Customer
package com.armin.self_editor;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class Customer implements ApplicationContextAware {
private String name;
private Address address;
private ApplicationContext applicationContext;
public Customer() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public ApplicationContext getApplicationContext() {
return applicationContext;
}
@Override
public String toString() {
return "Customer{" +
"name='" + name + '\'' +
", address=" + address +
'}';
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
armin-self-aware.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="customer" class="com.armin.self_editor.Customer">
<property name="name" value="armin"/>
<!-- <property name="address" value="四川省_眉山市_东坡区"/>-->
</bean>
</beans>
Test
package com.armin.self_aware;
import com.armin.self_editor.Customer;
public class Test {
public static void main(String[] args) {
MyClassPathApplicationContext ac = new MyClassPathApplicationContext("armin-self-aware.xml");
Customer bean = ac.getBean(Customer.class);
System.out.println(bean);
}
}
输出结果
> Task :spring-debug:Test.main()
扩展实现postProcessBeanFactory,添加自定义BeanPostProcessor
前置执行bean增强!
Customer{name='armin', address=Address{province='四川省', city='眉山市', area='东坡区'}}
简要执行流程
finishBeanFactoryInitialization() -> getBean() -> getBean() -> doGetBean() -> createBean() -> doCreateBean() -> initializeBean() -> applyBeanPostProcessorsBeforeInitialization()
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { //初始化返回结果为existingBean Object result = existingBean; //遍历 该工厂创建的bean的BeanPostProcessors列表 for (BeanPostProcessor processor : getBeanPostProcessors()) { // postProcessBeforeInitialization:在任何Bean初始化回调之前(如初始化Bean的afterPropertiesSet或自定义的init方法) // 将此BeanPostProcessor 应用到给定的新Bean实例。Bean已经填充了属性值。返回的Bean实例可能时原始Bean的包装器。 // 默认实现按原样返回给定的 Bean Object current = processor.postProcessBeforeInitialization(result, beanName); // 如果 current为null if (current == null) { //直接返回result,中断其后续的BeanPostProcessor处理 return result; } //让result引用processor的返回结果,使其经过所有BeanPostProcess对象的后置处理的层层包装 result = current; } //返回经过所有BeanPostProcess对象的后置处理的层层包装后的result return result; }