Spring注解驱动开发--bean的生命周期

前言

  bean的生命周期指的是 bean 的创建、初始化和销毁的过程。bean的创建是由容器完成的,但我们可以通过多种方式自定义bean的初始化和销毁的方法:容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法。

自定义初始化和销毁方法

     ① 通过@Bean指定init-method和destroy-method指定初始化和销毁方法;

@ComponentScan("com.atneusoft.bean")
@Configuration
public class MainConfigOfLifeCycle {
    
    @Bean(initMethod="init",destroyMethod="detory")
    public Car car(){
        return new Car();
    }

}

   同下

  class="com.atneusoft.bean.Person"  scope="prototype" destroy-method=""  init-method=""> 

 

  ② 通过让Bean实现相关接口

                      InitializingBean(定义初始化逻辑),
                      DisposableBean(定义销毁逻辑);

public class Cat implements InitializingBean, DisposableBean {

    public Cat() {
        System.out.println("Cat constructor...");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("cat afterPropertiesSet....");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("cat destroy....");
    }
}

 

     ③可以使用JSR250注解指定具体的方法

             @PostConstruct:在bean创建完成并且属性赋值完成;来执行初始化方法
             @PreDestroy:在容器销毁bean之前通知我们进行清理工作    

public class Car{

    public Cat() {
        System.out.println("Cat constructor...");
    }


    @PostConstruct
    public void init() {
        System.out.println("cat 。。construct ...初始化之后。。。。。");
    }

    @PreDestroy
    public void  destroy(){
        System.out.println("cat  destroy 之前");
    }
}

BeanPostProcessor 接口

     可以通过上面提到的三种方式进行bean的初始化方法

        bean的后置处理器: 在bean初始化前后进行一些处理工作
               postProcessBeforeInitialization:在初始化之前工作
               postProcessAfterInitialization:在初始化之后工作

          注意:自定义bean的后置处理器将作用于所有的bean初始化前后,而bean的初始化方法只作用于当前bean

public class MyPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessBeforeInitialization " + beanName +"===>" + bean);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessAfterInitialization " + beanName +"===>" + bean);
        return bean;
    }
}


public
interface BeanPostProcessor { /** * Apply this {@code BeanPostProcessor} to the given new bean instance before any bean * initialization callbacks (like InitializingBean's {@code afterPropertiesSet} * or a custom init-method). The bean will already be populated with property values. * The returned bean instance may be a wrapper around the original. *

The default implementation returns the given {@code bean} as-is. * @param bean the new bean instance * @param beanName the name of the bean * @return the bean instance to use, either the original or a wrapped one; * if {@code null}, no subsequent BeanPostProcessors will be invoked * @throws org.springframework.beans.BeansException in case of errors * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet */ @Nullable default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } /** * Apply this {@code BeanPostProcessor} to the given new bean instance after any bean * initialization callbacks (like InitializingBean's {@code afterPropertiesSet} * or a custom init-method). The bean will already be populated with property values. * The returned bean instance may be a wrapper around the original. *

In case of a FactoryBean, this callback will be invoked for both the FactoryBean * instance and the objects created by the FactoryBean (as of Spring 2.0). The * post-processor can decide whether to apply to either the FactoryBean or created * objects or both through corresponding {@code bean instanceof FactoryBean} checks. *

This callback will also be invoked after a short-circuiting triggered by a * {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method, * in contrast to all other {@code BeanPostProcessor} callbacks. *

The default implementation returns the given {@code bean} as-is. * @param bean the new bean instance * @param beanName the name of the bean * @return the bean instance to use, either the original or a wrapped one; * if {@code null}, no subsequent BeanPostProcessors will be invoked * @throws org.springframework.beans.BeansException in case of errors * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet * @see org.springframework.beans.factory.FactoryBean */ @Nullable default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } }

Bean的后置处理器的原理

自定义的bean的后置处理器,将自定义好的处理器置于容器当中,postProcessBeforeInitialization 方法处打断点,启动注解的方式spring容器,跟踪方法调用栈如下

@Configuration
public class PostProcessConfig {

    @Bean
    public MyPostProcessor myPostProcessor(){
        return new MyPostProcessor();
    }
}

 

@Test
    void Test01() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(PostProcessConfig.class);
        Cat cat = applicationContext.getBean(Cat.class);
        applicationContext.close();
        System.out.println(cat);
    }

调用栈如下

Spring注解驱动开发--bean的生命周期_第1张图片

 

 

创建bean的关键代码如下

      try {
            populateBean(beanName, mbd, instanceWrapper);//为bean的各种属性赋值,在bean的始化之前完成
            exposedObject = initializeBean(beanName, exposedObject, mbd);//初始化bean,
        }

初始化bean方法如下

    protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction) () -> {
                invokeAwareMethods(beanName, bean);
                return null;
            }, getAccessControlContext());
        }
        else {
            invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);//自定义处理器的调用,作用于全局
        }

        try {
            invokeInitMethods(beanName, wrappedBean, mbd);//执行自定义初始化方法,即执行以上提到的初始化bean的三种方式的初始化方法
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    (mbd != null ? mbd.getResourceDescription() : null),
                    beanName, "Invocation of init method failed", ex);
        }
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);//自定义处理器的调用
        }

        return wrappedBean;
    } 
  
 
applyBeanPostProcessorsBeforeInitialization的执行
    @Override
    public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
            throws BeansException {

        Object result = existingBean;
//遍历得到容器中所有的BeanPostProcessor;挨个执行beforeInitialization
//一但返回null,跳出for循环,不会执行后面的BeanPostProcessor.postProcessorsBeforeInitialization
for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessBeforeInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }

所有的bean处理器

Spring注解驱动开发--bean的生命周期_第2张图片

 

 

 Spring底层对BeanPostProcessor的使用

  在Spring的底层,在bean的创建、初始化和赋值的过程当中大量的使用到了BeanPostProcess,常用的BeanPostProcessor:

Spring注解驱动开发--bean的生命周期_第3张图片

 ①ApplicationContextAwareProcessor    ====>  给容器中注入IOC 组件

 @Nullable
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (!(bean instanceof EnvironmentAware) && !(bean instanceof EmbeddedValueResolverAware) && !(bean instanceof ResourceLoaderAware) && !(bean instanceof ApplicationEventPublisherAware) && !(bean instanceof MessageSourceAware) && !(bean instanceof ApplicationContextAware)) {
            return bean;
        } else {
            AccessControlContext acc = null;
            if (System.getSecurityManager() != null) {
                acc = this.applicationContext.getBeanFactory().getAccessControlContext();
            }

            if (acc != null) {
                AccessController.doPrivileged(() -> {
                    this.invokeAwareInterfaces(bean);
                    return null;
                }, acc);
            } else {
                this.invokeAwareInterfaces(bean);
            }

            return bean;
        }
    }

    private void invokeAwareInterfaces(Object bean) {
        if (bean instanceof EnvironmentAware) {
            ((EnvironmentAware)bean).setEnvironment(this.applicationContext.getEnvironment());
        }

        if (bean instanceof EmbeddedValueResolverAware) {
            ((EmbeddedValueResolverAware)bean).setEmbeddedValueResolver(this.embeddedValueResolver);
        }

        if (bean instanceof ResourceLoaderAware) {
            ((ResourceLoaderAware)bean).setResourceLoader(this.applicationContext);
        }

        if (bean instanceof ApplicationEventPublisherAware) {
            ((ApplicationEventPublisherAware)bean).setApplicationEventPublisher(this.applicationContext);
        }

        if (bean instanceof MessageSourceAware) {
            ((MessageSourceAware)bean).setMessageSource(this.applicationContext);
        }

        if (bean instanceof ApplicationContextAware) {
            ((ApplicationContextAware)bean).setApplicationContext(this.applicationContext);
        }

    }

如下进行IOC容器的注入

public class Color implements ApplicationContextAware {

    private ApplicationContext applicationContext;

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

②AsyncAnnotationBeanPostProcessor  ====》  处理@Async标注的异步方法

③AutowiredAnnotationBeanPostProcessor  ====》对象创建完成以后,处理@Autowired标注的所有属性进行赋值

public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
        implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {

④BeanValidationPostProcessor   ====》bean创建完,属性赋值以后(populateBean方法为给属性赋值)进行数据的校验

属性赋值==》数据校验==》初始化

public class BeanValidationPostProcessor implements BeanPostProcessor, InitializingBean {
    

⑤InitDestroyAnnotationBeanPostProcessor ====》 处理@PostConstruct 、@PreDestroy注解

    public class InitDestroyAnnotationBeanPostProcessor
        implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor, PriorityOrdered, Serializable {


       /**
     * Specify the init annotation to check for, indicating initialization
     * methods to call after configuration of a bean.
     * 

Any custom annotation can be used, since there are no required * annotation attributes. There is no default, although a typical choice * is the JSR-250 {@link javax.annotation.PostConstruct} annotation. */ public void setInitAnnotationType(Classextends Annotation> initAnnotationType) { this.initAnnotationType = initAnnotationType; } /** * Specify the destroy annotation to check for, indicating destruction * methods to call when the context is shutting down. *

Any custom annotation can be used, since there are no required * annotation attributes. There is no default, although a typical choice * is the JSR-250 {@link javax.annotation.PreDestroy} annotation. */ public void setDestroyAnnotationType(Classextends Annotation> destroyAnnotationType) { this.destroyAnnotationType = destroyAnnotationType; } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
//找到当前bean的生命周期注解标注的方法 LifecycleMetadata metadata
= findLifecycleMetadata(bean.getClass()); try {
       //利用反射调用bean的初始化方法 metadata.invokeInitMethods(bean, beanName); }
catch (InvocationTargetException ex) { throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException()); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Failed to invoke init method", ex); } return bean; }

public void invokeInitMethods(Object target, String beanName) throws Throwable {
            Collection checkedInitMethods = this.checkedInitMethods;
            Collection initMethodsToIterate =
                    (checkedInitMethods != null ? checkedInitMethods : this.initMethods);
            if (!initMethodsToIterate.isEmpty()) {
                for (LifecycleElement element : initMethodsToIterate) {
                    if (logger.isTraceEnabled()) {
                        logger.trace("Invoking init method on bean '" + beanName + "': " + element.getMethod());
                    }
                    element.invoke(target);
                }
            }
        }
@Component
public class Dog implements ApplicationContextAware {
    
    //@Autowired
    private ApplicationContext applicationContext;
    
    public Dog(){
        System.out.println("dog constructor...");
    }
    
    //对象创建并赋值之后调用
    @PostConstruct
    public void init(){
        System.out.println("Dog....@PostConstruct...");
    }
    
    //容器移除对象之前
    @PreDestroy
    public void detory(){
        System.out.println("Dog....@PreDestroy...");
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        // TODO Auto-generated method stub
        this.applicationContext = applicationContext;
    }    

}

 

 

Spring注解驱动开发--bean的生命周期_第4张图片

 

 

 Spring注解驱动开发--bean的生命周期_第5张图片

 

 如上spring底层对 bean赋值,注入其他组件,@Autowired,生命周期注解功能,@Async等等都使用到了 BeanPostProcessor;

bean的生命周期总结

bean的生命周期:
          bean创建---初始化----销毁的过程
  容器管理bean的生命周期;
  我们可以自定义初始化和销毁方法;容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法
 
  构造(对象创建)
          单实例:在容器启动的时候创建对象
          多实例:在每次获取的时候创建对象
 
  BeanPostProcessor.postProcessBeforeInitialization
  初始化
          对象创建完成,并赋值好,调用初始化方法。。。
  BeanPostProcessor.postProcessAfterInitialization
  销毁:
          单实例:容器关闭的时候
          多实例:容器不会管理这个bean;容器不会调用销毁方法;
 
 

 

你可能感兴趣的:(Spring注解驱动开发--bean的生命周期)