spring中BeanPostProcessor,InitializingBean,@PostConstruct以及类构造函数的执行顺序

2023-01-19 09:47:19

基本概念

无参构造

bean被初始化时第一时间调用

public InitStarter() {
        LOG.info("InitStarter Constructor 2001");
    }

BeanPostProcessor

    BeanPostProcessor接口提供了初始化bean时的前置接口和后置接口,我们只需要实现BeanPostProcessor中对应的接口就可以bean初始化前后做自己的逻辑处理。

@Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        InitStarter initStarter = (InitStarter)applicationContext.getBean("initStarter");
        LOG.info("initStarter postProcessBeforeInitialization:"+initStarter);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        InitStarter initStarter = (InitStarter)applicationContext.getBean("initStarter");
        LOG.info("initStarter postProcessAfterInitialization:"+initStarter);
        return bean;
    }

@PostConstruct

    在类中的方法上加上注解@PostConstruct后,初始化bean的前会调用被注解的方法。

@PostConstruct
    private void init(){
        LOG.info("InitStarter PostConstruct Annotation 2001");
    }

InitializingBean

    InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是实现该接口的类,在初始化bean的时候都会执行该方法。

@Override
    public void afterPropertiesSet() throws Exception {
        LOG.info("InitStarter afterPropertiesSet 2001");
    }

执行代码

InitStarter类,针对bean自身的逻辑处理
@Slf4j
@Component
@Order(value = 2001)
public class InitStarter implements InitializingBean {

    public InitStarter() {
        LOG.info("InitStarter Constructor 2001");
    }

    @PostConstruct
    private void init(){
        LOG.info("InitStarter PostConstruct Annotation 2001");
    }


    @Override
    public void afterPropertiesSet() throws Exception {
        LOG.info("InitStarter afterPropertiesSet 2001");
    }
}

CustomBeanPostProcessor 针对所有项目的bean处理逻辑

@Slf4j
@Component
public class CustomBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware {

    private ApplicationContext applicationContext;

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        InitStarter initStarter = (InitStarter)applicationContext.getBean("initStarter");
        LOG.info("initStarter postProcessBeforeInitialization:"+initStarter);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        InitStarter initStarter = (InitStarter)applicationContext.getBean("initStarter");
        LOG.info("initStarter postProcessAfterInitialization:"+initStarter);
        return bean;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

执行结果

InitStarter Constructor 2001
initStarter postProcessBeforeInitialization:com.test.InitStarter@254cc548
InitStarter PostConstruct Annotation 2001
InitStarter afterPropertiesSet 2001
initStarter postProcessAfterInitialization:com.test.InitStarter@254cc548

由此可见初始化Bean的先后顺序为:

Bean本身的构造函数
BeanPostProcessor的postProcessBeforeInitialization方法
类中添加了注解@PostConstruct 的方法
InitializingBean的afterPropertiesSet方法
BeanPostProcessor的postProcessAftrInitialization方法

至于为什么是这样的执行顺序,后期有空会写个源码解析。。。

  • 作者:小左的博客
  • 原文链接:https://blog.csdn.net/longloveqing/article/details/114920595
    更新时间:2023-01-19 09:47:19