refresh() ->postProcessBeanFactory()

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值