欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring 中 Bean 的生命周期

程序员文章站 2022-05-24 18:06:21
...

对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, 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 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)
@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
相关标签: Spring 生命周期