通过名字我们就可以猜测这个bean的作用:BeanFactory的后置处理器。BeanFactoryPostProcessor是实现spring容器功能扩展的重要接口,我们通过它可以动态修改bean属性值,实现bean动态代理等,首先看一下接口的定义。
public interface BeanFactoryPostProcessor { /** * Modify the application context's internal bean factory after its standard * initialization. All bean definitions will have been loaded, but no beans * will have been instantiated yet. This allows for overriding or adding * properties even to eager-initializing beans. * @param beanFactory the bean factory used by the application context * @throws org.springframework.beans.BeansException in case of errors */ void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException; }
注释写的很清楚:在Spring容器初始化之后修改BeanFactory的内容,此时所有的bean已经定义过,但是没有还初始化。此时允许重写我们修改bean的定义。
下面以学生、汽车为模型,简单学习一下BeanFactoryPostProcessor的使用,顺便复习一下spring中Bean的加载流程和动态代理。
学生类
public class Student implements InitializingBean,BeanPostProcessor { Car car; public void start(){ System.out.println("start --->执行"); car.run(); } @Override public void afterPropertiesSet() throws Exception { System.out.println("afterPropertiesSet 执行"); if(car == null){ System.out.println("car not setting"); }else { System.out.println("car installed"); } } public Student() { System.out.println("Student 构造器 执行"); if(car == null){ System.out.println("car not setting"); }else { System.out.println("car installed"); } } @PostConstruct public void init(){ System.out.println("PostConstruct 执行"); if(car == null){ System.out.println("car not setting"); }else { System.out.println("car installed"); } } public void setCar(Car car) { this.car = car; }
汽车接口
public interface Car { void run(); }
我们将 Student 注入Spring 容器
@Bean(initMethod = "start") public Student student(Car car1){ Student student = new Student(); student.setCar(car1); return student; }
汽车接口没有实现,这么启动肯定报错。我们可以通过动态代理实现Car接口并将它放入Spring容器中
public class SpecialBeanForCar implements BeanFactoryPostProcessor { String name; @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException { System.out.println("postProcessBeanFactory running"); BeanDefinitionRegistry registry = (BeanDefinitionRegistry) configurableListableBeanFactory; GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition(); genericBeanDefinition.setBeanClass(MyFactory.class); genericBeanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON); genericBeanDefinition.setAutowireCandidate(true); registry.registerBeanDefinition("car", genericBeanDefinition); } public static class MyFactory implements FactoryBean<Car>, InvocationHandler { @Override public Car getObject() throws Exception { System.out.println("CarFactory to build car"); return (Car) Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[]{Car.class}, this); } @Override public Class<?> getObjectType() { return Car.class; } @Override public boolean isSingleton() { return true; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("汽车跑起来了"); return null; } } }
将 SpecialBeanForCar注入Spring
@Bean public SpecialBeanForCar specialBeanForCar(){ return new SpecialBeanForCar(); }
执行Application后打印如下
postProcessBeanFactory running Student 构造器 执行 car not setting PostConstruct 执行 car installed afterPropertiesSet 执行 car installed start --->执行 汽车跑起来了
通过结果我们可以知道Spring Bean的加载流程
BeanFactoryPostProcessor ---> 普通Bean构造方法 ---> 设置依赖或属性 ---> @PostConstruct ---> InitializingBean ---> initMethod