Springboot bean加载机制及后置处理器

/**
 * @author guchuang
 * @DESC 1.本实例的构造函数, 实例化对象(实例化走的是普通java对象实例化的流程),
 *   此时全局变量(注入的服务为空),service服务实例化之后(完成构造函数调用)便可以注入到其它服务之中
 * 2.注入添加了@Autowired注解的服务(即设置实例变量的值)
 * 3.调用BeanNameAware.setBeanName(), 设置bean的名字,名字由注册服务时指定(本实例为a1),不指定的话默认为类名的首字母小写
 * 4.ApplicationContextAware.setApplicationContext(), 设置bean实例运行的上下文ApplicationContext
 * 5.调用@PostConstruct注解的方法, 此时已经完成了依赖注入
 * 6.InitializingBean.afterPropertiesSet(), bean的属性全部设置完毕后调用
 * 7.BeanPostProcessor.postProcessBeforeInitialization() & BeanPostProcessor.postProcessAfterInitialization(), 后置处理器,会被多次调用,每个服务实例都被被调用一次
 *   postProcessBeforeInitialization() 在@PostConstruct之前调用
 *   postProcessAfterInitialization()  在@PostConstruct之后调用
 */
@Service
public class TestA implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, BeanPostProcessor {
    private int order = 1;

    @Autowired
    private TestB testB;


    public TestA() {
        job();
        MyLog.info("Constructor TestA");
        MyLog.sleep(100);
    }

    @Override
    public void setBeanName(String name) {
        MyLog.info("BeanNameAware setBeanName, name:" + name);
    }


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        MyLog.info("ApplicationContextAware setApplicationContext, applicationContext:" + applicationContext);
    }

    /**
     * 依赖注入完成后调用的方法(此时@Autowired的服务全部已经初始化),即使没有外部依赖,该方法也需要被调用一次
     */
    @PostConstruct
    public void postConstruct() {
        MyLog.info("PostConstruct TestA" + " ,testB is null? " + (testB == null));
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        MyLog.info("InitializingBean afterPropertiesSet");
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        MyLog.info("BeanFactory setBeanFactory");
        //MyLog.info("BeanFactory setBeanFactory, beanFactory:" + beanFactory);
    }
    /*@Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        print("BeanFactoryPostProcessor postProcessBeanFactory, beanFactory:" + beanFactory);
    }*/

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.contains("123")) {
            MyLog.info("BeanPostProcessor postProcessBeforeInitialization, bean:" + bean + ", beanName:" + beanName);
        }
        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.contains("123")) {
            MyLog.info("BeanPostProcessor postProcessAfterInitialization, bean:" + bean + ", beanName:" + beanName);
        }
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }
    
    /*public void print(Object o) {
        MyLog.info(order++ + "." + o + "==========================================");
        MyLog.info(testB != null);
    }*/

    public void job() {
        new Thread(() -> {
            MyLog.info("async run1,result: " + (testB != null));

            MyLog.sleep(4000);
            MyLog.info("async run2,result: " + (testB != null));

        }).start();
    }
}
@Service
public class TestB {
    @Autowired
    TestA a;

    public TestB() {
        MyLog.info("Constructor TestB");
        MyLog.sleep(100);
    }

    @PostConstruct
    public void postConstruct() {
        MyLog.info("PostConstruct TestB" + " ,a is null? " + (a == null));
    }

    public String foo() {
        return "hello world, i am b";
    }

}

bean的后置处理器

@Service
public class TestBean implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean {

    @Value("${server.port}")
    String port;

    @Autowired
    Tmp1 tmp1;

    TestBean() {
        MyLog.info("Constructor TestBean");
    }

    @PostConstruct
    public void init() {
        MyLog.info("PostConstructor TestBean, port:" + port);
    }

    @Override
    public void setBeanName(String name) {
        MyLog.info("BeanNameAware setBeanName, name:" + name);
    }


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        MyLog.info("ApplicationContextAware setApplicationContext, applicationContext:" + applicationContext);
    }

    @Override
    public void afterPropertiesSet() {
        MyLog.info("InitializingBean afterPropertiesSet, port:" + port);
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        MyLog.info("BeanFactory setBeanFactory");
        //MyLog.info("BeanFactory setBeanFactory, beanFactory:" + beanFactory);
    }

}
/**
 * @description: bean工厂后置处理器,spring读取完bean定义后,在后续处理之前调用一次,给予修改bean信息的机会
 * @author: guchuang
 * @create: 2019-10-11 08:55
 **/
@Service
public class TestBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    /**
     * 这个方法只会被调用一次
     * 所有的bean definition已经加载完成,尚未初始化,这里可以修改bean的定义
     * bean definition包含bean对象的所有信息(接口,继承,属性,方法,注解...)
     * @param beanFactory
     * @throws BeansException
     */
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        //MyLog.debug(beanFactory.getBean(TestBean.class));
        MyLog.info("postProcessBeanFactory");
    }
}
/**
 * @description: bean对象后置处理器,在bean初始化后期过程中调用
 * bean的生命周期:
 *  1.实例化(调用构造函数生成对象)
 *  2.初始化(注入属性、设置beanName、设置beanFactory、设置applicationContext、调用@PostConstructor方法,调用afterpropertiesSet方法)
 *      BeanPostProcessor作用于: 调用@PostConstructor方法,调用afterpropertiesSet方法前后
 *      调用完postProcessAfterInitialization表示bean已经完全初始化,可以放在bean工厂且能正常使用
 * @author: guchuang
 * @create: 2019-10-09 10:07
 **/
@Component
public class TestBeanPostProcessor implements BeanPostProcessor {

    public TestBeanPostProcessor() {
        MyLog.info("Constructor TestPostProcessor");
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.contains("test")) {
            MyLog.info("BeanPostProcessor postProcessBeforeInitialization, bean:" + bean + ", beanName:" + beanName);
        }
        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.contains("test")) {
            MyLog.info("BeanPostProcessor postProcessAfterInitialization, bean:" + bean + ", beanName:" + beanName);
        }
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }
}
/**
 * @description: bean实例化(类似new Object())后置处理器,在调用构造函数先后(紧挨着)分别调用这里的两个方法
 * @author: guchuang
 * @create: 2019-10-10 09:31
 **/
@Component
public class TestInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        if (beanName.contains("test")) {
            MyLog.info("postProcessBeforeInstantiation, bean:" + beanClass + ", beanName:" + beanName);
        }
        return null;
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        if (beanName.contains("test")) {
            MyLog.info("postProcessBeforeInstantiation, bean:" + bean + ", beanName:" + beanName);
        }
        return true;
    }

    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
        if (beanName.contains("test")) {
            MyLog.info("postProcessPropertyValues, bean:" + bean + ", beanName:" + beanName + ", pvs:" + pvs);
        }
        return pvs;
    }
}
原文地址:https://www.cnblogs.com/gc65/p/12848579.html