SpringBoot bean的常用扩展点
了解Spring这些扩展点,有助于我们编写更优雅的代码。扩展点的具体应用实践,我们可以多看优秀的源码借鉴思路。
扩展点顺序
- 【1】BeanFactoryPostProcessor postProcessBeanFactory. 【BeanFactoryPostProcessor beanFactory】
- 【2】InstantiationAwareBeanPostProcessor postProcessBeforeInstantiation beanName:chat. 【实现 InstantiationAwareBeanPostProcessor接口 【实例化,非初始化】前。所有bean生效】
- 【3】Chat construct. 【bean 无参构造函数调用,实例化】
- 【4】InstantiationAwareBeanPostProcessor postProcessAfterInstantiation beanName:chat. 【实现 InstantiationAwareBeanPostProcessor接口 【实例化,非初始化】后】。所有bean生效
- 【5】BeanNameAware setBeanName, name: chat. 【实现 BeanNameAware接口】
- 【6】BeanFactoryAware setBeanFactory. 【实现 BeanFactoryAware 接口,传入bean容器】
- 【7】ApplicationContextAware setApplicationContext. 【实现ApplicationContext接口,其继承自BeanFactory】
- 【8】BeanPostProcessor postProcessBeforeInitialization. 【BeanPostProcessor 初始化前调用。所有bean 都可生效】
- 【9】Chat PostConstruct. 【init方法 @PostConstruct注解,初始化bean】
- 【10】Chat afterPropertiesSet. 【bean 实现InitializingBean接口,初始化bean】
- 【11】BeanPostProcessor postProcessAfterInitialization. 【BeanPostProcessor 初始化后调用。所有bean 都可生效】
- 【12】Chat PreDestroy. 【bean 销毁前调用】
- 【13】Chat destroy.【bean 销毁时调用】
代码
bean 举例
@Service
public class Chat implements InitializingBean, BeanNameAware, BeanFactoryAware, ApplicationContextAware, DisposableBean {
    private static ApplicationContext appContext;
    public Chat() {
        System.out.println("【3】Chat construct. 【bean 无参构造函数调用,实例化】");
    }
    @PostConstruct
    public void init() {
        System.out.println("【9】Chat PostConstruct. 【init方法 @PostConstruct注解,初始化bean】");
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("【10】Chat afterPropertiesSet. 【bean 实现InitializingBean接口,初始化bean】");
    }
    public void say() {
        System.out.println("say something");
    }
    /**
     * 单个bean 生效
     */
    @Override
    public void setBeanName(String name) {
        System.out.println("【5】BeanNameAware setBeanName, name: " + name + ". 【实现 BeanNameAware接口】");
    }
    /**
     * BeanFactoryAware  单个bean生效
     * @throws BeansException
     */
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("【6】BeanFactoryAware setBeanFactory. 【实现 BeanFactoryAware 接口,传入bean容器】");
    }
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("【7】ApplicationContextAware setApplicationContext. 【实现ApplicationContext接口,其继承自BeanFactory】");
        appContext = applicationContext;
    }
    public <T> T getBean(String beanName, Class<T> requiredType) {
        return appContext.getBean(beanName, requiredType);
    }
    @PreDestroy
    public void preDestroy() {
        System.out.println("【12】Chat PreDestroy. 【bean 销毁前调用】");
    }
    public void destroy() throws Exception {
        System.out.println("【13】Chat destroy.【bean 销毁时调用】");
    }
}
ApplicationContextAware 容器上下文 举例
@Component
public class AppContext implements ApplicationContextAware {
    private static ApplicationContext appContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("ApplicationContextAware setApplicationContext. 【实现ApplicationContext接口】");
        appContext = applicationContext;
    }
    public <T> T getBean(String beanName, Class<T> requiredType) {
        return appContext.getBean(beanName, requiredType);
    }
    public <T> T getBean(Class<T> requiredType) {
        return appContext.getBean(requiredType);
    }
}
InstantiationAwareBeanPostProcessor 实例化前后 举例
@Component
public class InstantiationBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
    /**
     * bean 实例化(new obj)之前调用
     */
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        if ("chat".equals(beanName)) {
            System.out.println("【2】InstantiationAwareBeanPostProcessor postProcessBeforeInstantiation beanName:" + beanName + ". 【实现 InstantiationAwareBeanPostProcessor接口 【实例化,非初始化】前。所有bean生效】");
        }
        return null;
    }
    /**
     * bean 实例化(new obj)之后调用
     */
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        if ("chat".equals(beanName)) {
            System.out.println("【4】InstantiationAwareBeanPostProcessor postProcessAfterInstantiation beanName:" + beanName + ". 【实现 InstantiationAwareBeanPostProcessor接口 【实例化,非初始化】后】。所有bean生效");
        }
        return true;
    }
    /**
     * 所有bean 都可生效
     * InstantiationAwareBeanPostProcessor 继承自 BeanPostProcessor
     * 初始化bean前调用,bean放到spring上下文之前
     */
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("chat")) {
            System.out.println("【8】BeanPostProcessor  postProcessBeforeInitialization. 【BeanPostProcessor 初始化前调用。所有bean 都可生效】");
        }
        return bean;
    }
    /**
     * 所有bean 都可生效
     * InstantiationAwareBeanPostProcessor 继承自 BeanPostProcessor
     * 初始化bean后调用,bean放到spring上下文之后
     */
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("chat")) {
            System.out.println("【11】BeanPostProcessor  postProcessAfterInitialization. 【BeanPostProcessor 初始化后调用。所有bean 都可生效】");
        }
        return bean;
    }
}
BeanFactoryPostProcessor 容器 举例
@Component
public class BeanFactoryPostProcess implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("【1】BeanFactoryPostProcessor postProcessBeanFactory. 【BeanFactoryPostProcessor beanFactory】");
    }
}
BeanPostProcessor bean初始化前后 举例
前边的InstantiationAwareBeanPostProcessor 继承自 BeanPostProcessor,也会继承内部这两个方法。
@Component
public class BeanPostProcess implements BeanPostProcessor {
    /**
     * 所有bean 都可生效
     */
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("chat")) {
            System.out.println("【8】BeanPostProcessor  postProcessBeforeInitialization. 【BeanPostProcessor 初始化前调用。所有bean 都可生效】");
        }
        return bean;
    }
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("chat")) {
            System.out.println("【11】BeanPostProcessor  postProcessAfterInitialization. 【BeanPostProcessor 初始化后调用。所有bean 都可生效】");
        }
        return bean;
    }
}
总结
bean的生命周期和SpringBoot开发中常用扩展点。
- bean整个容器、上下文的构造。
- 各个bean的实例化前后、初始化前后,可干预的扩展点。