Spring 中 Bean 的生命周期

对beanFactory的修改

实例化BeanFactoryPostProcessor,实例化前后不会被调用BeanPostProcessor的方法。

  • BeanFactoryPostProcessorTest()
  • BeanFactoryPostProcessor.postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory): void
@Slf4j
@Component
public class BeanFactoryPostProcessorTest implements BeanFactoryPostProcessor {
    
    public BeanFactoryPostProcessorTest() {
        log.debug("BeanFactoryPostProcessorTest()");
    }

    /**
     * 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
     * @throws BeansException
     */
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        log.debug("BeanFactoryPostProcessor.postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory): void");
    }
}

实例化BeanPostProcessor

BeanPostProcessor实例化前后不会被调用BeanPostProcessor的方法。

  • BeanPostProcessorForPostProcessors()
  • BeanPostProcessorTest()
  • InstantiationAwareBeanPostProcessorTest()
@Slf4j
@Component
public class BeanPostProcessorTest implements BeanPostProcessor {

    public BeanPostProcessorTest() {
        log.debug("BeanPostProcessorTest()");
    }

    /**
     * The bean will already be populated with property values.(属性注入完毕)
     * before any bean initialization callbacks (like InitializingBean's {@code afterPropertiesSet} or a custom init-method).
     * The returned bean instance may be a wrapper around the original.
     *
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof BeanTest) {
            log.debug("BeanPostProcessor.postProcessBeforeInitialization(Object bean, String beanName): Object");
        }
        return bean;
    }

    /**
     * after any bean initialization callbacks (like InitializingBean's {@code afterPropertiesSet} or a custom init-method).
     * this callback will be invoked for both the FactoryBean(不是BeanFactory) instance and the objects created by the FactoryBean (as of(自从) Spring 2.0).
     *
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof BeanTest) {
            log.debug("BeanPostProcessor.postProcessAfterInitialization(Object bean, String beanName): Object");
        }
        return bean;
    }
}
@Slf4j
@Component
public class InstantiationAwareBeanPostProcessorTest implements InstantiationAwareBeanPostProcessor {

    public InstantiationAwareBeanPostProcessorTest() {
        log.debug("InstantiationAwareBeanPostProcessorTest()");
    }

    /**
     * before the target bean creation. The returned bean object may be a proxy to use instead of the target bean, suppressing default creation process of the target bean.
     * 可作用于BeanDefinition以及factory-method,If a non-null object is returned by this method, the bean creation process will be short-circuited.(即factory-method也不会被调用)
     *
     * @param beanClass BeanDefinition的Bean类型或者factory-method的返回值类型
     */
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        if (beanClass.equals(BeanTest.class)) {
            log.debug("InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation(Class<?> beanClass, String beanName): Object");
        }
        return null;
    }

    /**
     * after the bean has been instantiated, via a constructor or factory method,
     * before Spring property population (from explicit properties or autowiring) occurs.
     * This is the ideal callback for performing custom field injection on the given bean instance, right before Spring's autowiring kicks in.
     *
     * @return {@code true} if properties should be set on the bean; {@code false}
     * if property population should be skipped. Normal implementations should return {@code true}.
     * Returning {@code false} will also prevent any subsequent(随后的) InstantiationAwareBeanPostProcessor
     * instances being invoked on this bean instance.
     */
    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        if (bean instanceof BeanTest) {
            log.debug("InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation(Object bean, String beanName): boolean");
        }
        return true;
    }

    /**
     * Post-process *the given property values* before the factory applies them to the given bean, without any need for property descriptors.
     * <p>
     * Implementations should return {@code null} (the default) if they provide a custom {@link #postProcessPropertyValues} implementation, and {@code pvs} otherwise.
     * In a future version of this interface (with {@link #postProcessPropertyValues} removed), the default implementation will return the given {@code pvs} as-is directly.
     *
     * @return the actual property values to apply to the given bean (can be the passed-in
     * PropertyValues instance), or {@code null} which proceeds with the existing properties
     * but specifically continues with a call to {@link #postProcessPropertyValues}
     * (requiring initialized {@code PropertyDescriptor}s for the current bean class)
     */
    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        if (bean instanceof BeanTest) {
            log.debug("InstantiationAwareBeanPostProcessor.postProcessProperties(PropertyValues pvs, Object bean, String beanName): PropertyValues");
        }
        return null;
    }

    /**
     * 与postProcessProperties相比需要额外的PropertyDescriptor[]参数
     * deprecated as of 5.1, in favor of {@link #postProcessProperties(PropertyValues, Object, String)}
     */
    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
        return pvs;
    }

    // InstantiationAwareBeanPostProcessor 继承于BeanPostProcessor,在合适的时机如下方法也会被调用

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}
@Slf4j
@Component
public class BeanPostProcessorForPostProcessors implements BeanPostProcessor {

    public BeanPostProcessorForPostProcessors() {
        log.debug("BeanPostProcessorForPostProcessors()");
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        // 并不会作用于这些类
        if (bean instanceof BeanFactoryPostProcessor) {
            log.debug("before BeanFactoryPostProcessor, beanClass: " + bean.getClass().getName());
        } else if (bean instanceof BeanPostProcessor) {
            log.debug("before BeanPostProcessor, beanClass: " + bean.getClass().getName());
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        // 并不会作用于这些类
        if (bean instanceof BeanFactoryPostProcessor) {
            log.debug("after BeanFactoryPostProcessor, beanClass: " + bean.getClass().getName());
        } else if (bean instanceof BeanPostProcessor) {
            log.debug("after BeanPostProcessor, beanClass: " + bean.getClass().getName());
        }
        return bean;
    }
}

Bean的生命周期

@Slf4j
public class BeanTest implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, CommandLineRunner, DisposableBean {

    public BeanTest() {
        log.debug("constructor");
    }

    @Autowired
    public void setBeanTest(BeanTest beanTest) {
        log.debug("BeanTest.setBeanTest(BeanTest beanTest): void");
    }

    @Override
    public void setBeanName(String name) {
        log.debug("BeanNameAware.setBeanName(String name): void");
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        log.debug("BeanFactoryAware.setBeanFactory(BeanFactory beanFactory): void, factoryClass: " + beanFactory.getClass().getName());
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        log.debug("ApplicationContextAware.setApplicationContext(ApplicationContext applicationContext): void, ctxClass: " + applicationContext.getClass().getName());
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        log.debug("InitializingBean.afterPropertiesSet(): void");
    }

    /**
     * 通过@Bean的initMethod属性指定
     * Not commonly used, given that(考虑到) the method may be called programmatically directly within the body of a Bean-annotated method.
     */
    public void initMethod() {
        log.debug("init-method");
    }
    
    @Override
    public void run(String... args) throws Exception {
        log.debug("run");
    }

    @Override
    public void destroy() throws Exception {
        log.debug("DisposableBean.destory(): void");
    }

    /**
     * 通过@Bean的destroyMethod属性指定
     * a method to call on the bean instance upon closing the application context.
     * As a convenience to the user, the container will attempt to infer a destroy method against an object returned from the {@code @Bean} method.
     * This 'destroy method inference' is currently limited to detecting only public, no-arg methods named 'close' or 'shutdown'.
     * The method may be declared at any level of the inheritance hierarchy and will be detected regardless of the return type of the {@code @Bean} method
     * (i.e., detection occurs reflectively against the bean instance itself at creation time).
     */
    public void destroyMethod() {
        log.debug("destory-method");
    }
    
}

实例化Bean(不包括BeanPostProcessor、BeanFactoryPostProcessor)

实例化相关的三个调用

  • InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation(Class<?> beanClass, String beanName): Object
  • constructor
  • InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation(Object bean, String beanName): boolean

属性注入

在设置属性前,可以修改属性值,或者添加删除属性

  • InstantiationAwareBeanPostProcessor.postProcessProperties(PropertyValues pvs, Object bean, String beanName): PropertyValues

属性赋值

  • BeanTest.setBeanTest(BeanTest beanTest): void

三个Aware接口设置属性

  • BeanNameAware.setBeanName(String name): void
  • BeanFactoryAware.setBeanFactory(BeanFactory beanFactory): void, factoryClass: org.springframework.beans.factory.support.DefaultListableBeanFactory
  • ApplicationContextAware.setApplicationContext(ApplicationContext applicationContext): void, ctxClass: org.springframework.context.annotation.AnnotationConfigApplicationContext

初始化Bean(init-method)

初始化前

  • 调用所有的BeanPostProcessor.postProcessBeforeInitialization(Object bean, String beanName): Object
  • InitializingBean.afterPropertiesSet(): void

初始化

  • init-method

初始化后

  • 调用所有的BeanPostProcessor.postProcessAfterInitialization(Object bean, String beanName): Object
  • t.i.d.springboot.lifecycle.LifeCycleApp : Started LifeCycleApp in 1.184 seconds (JVM running for 2.175)
  • 调用所有的CommandLineRunner.run(String… args): void
@ComponentScan(basePackageClasses = LifeCycleApp.class)
public class LifeCycleApp {

    @Bean(initMethod = "initMethod", destroyMethod = "destroyMethod")
    BeanTest beanTest() {
        return new BeanTest();
    }

    public static void main(String[] args) {
        new SpringApplicationBuilder(LifeCycleApp.class)
            .web(WebApplicationType.NONE)
            .run(args);
    }
}

销毁Bean

  • DisposableBean.destory(): void
  • destory-method
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值