目录

spring注解驱动之Bean生命周期

Bean指定初始化和销毁方法

经常用在数据源初始化时给参数赋值,销毁时关闭连接

指定初始化和销毁方法有两种,一种是通过@Bean指定init-method和destroy-method;

还有一种是通过让Bean实现InitializingBean定义初始化逻辑,实现DisposableBean定义销毁逻辑

注意
DisposableBean和destroy-method不能共用,init-method和InitializingBean可以共用,先执行afterPropertiesSet,再执行init方法

演示:

Bean

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.eh.bean;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Data
public class Person {
    private String name;
    private Integer age;

    public Person() {
        log.info("=====>执行构造方法");
    }

    public void init() {
        log.info("=====>初始化...");
    }

    public void destroy() {
        log.info("=====>销毁...");
    }
}

定义init和destroy

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package com.eh.config;

import com.eh.bean.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MainConfig {


    /**
     * bean的生命周期:
     * bean创建---初始化----销毁的过程
     * 容器管理bean的生命周期;
     * 我们可以自定义初始化和销毁方法;容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法
     * <p>
     * 构造(对象创建)
     * 单实例:在容器启动的时候创建对象
     * 多实例:在每次获取的时候创建对象
     * <p>
     * 初始化:
     * 对象创建完成,并赋值好,调用初始化方法。。。
     * <p>
     * 销毁:
     * 单实例:容器关闭的时候
     * 多实例:容器只负责创建对象但不会管理这个bean,所以容器不会调用销毁方法;
     *
     */
    @Bean(initMethod = "init", destroyMethod = "destroy")
    public Person person() {
        return new Person();
    }
}

测试:

1
2
3
4
public static void main(String[] args) {
    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
    applicationContext.close();
}

输出

1
2
3
23:48:24.864 [main] INFO  com.eh.bean.Person.<init>(Person.java:13) - =====>执行构造方法
23:48:24.874 [main] INFO  com.eh.bean.Person.init(Person.java:17) - =====>初始化...
23:48:24.917 [main] INFO  com.eh.bean.Person.destroy(Person.java:21) - =====>销毁...

InitializingBean和DisposableBean

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.eh.bean;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

@Slf4j
@Data
public class Person implements InitializingBean, DisposableBean {
    private String name;
    private Integer age;

    public Person() {
        log.info("=====>执行构造方法");
    }

    public void init() {
        log.info("=====>初始化...");
    }

    public void destroy() {
        log.info("=====>销毁...");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        log.info("=====>afterPropertiesSet");
    }
}
1
2
3
4
@Bean(initMethod = "init")
public Person person() {
    return new Person();
}

测试结果:

1
2
3
4
00:05:52.570 [main] INFO  com.eh.bean.Person.<init>(Person.java:15) - =====>执行构造方法
00:05:52.571 [main] INFO  com.eh.bean.Person.afterPropertiesSet(Person.java:28) - =====>afterPropertiesSet
00:05:52.572 [main] INFO  com.eh.bean.Person.init(Person.java:19) - =====>初始化...
00:05:52.591 [main] INFO  com.eh.bean.Person.destroy(Person.java:23) - =====>销毁...

@PostConstruct和@PreDestroy

这两个注解是JSR250定义的

  • @PostConstruct:在bean创建完成并且属性赋值完成;来执行初始化方法

    1
    2
    3
    4
    5
    
    @Documented
    @Retention (RUNTIME)
    @Target(METHOD)
    public @interface PostConstruct {
    }
    
  • @PreDestroy:在容器销毁bean之前通知我们进行清理工作

    1
    2
    3
    4
    5
    
    @Documented
    @Retention (RUNTIME)
    @Target(METHOD)
    public @interface PreDestroy {
    }
    

测试:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package com.eh.bean;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

@Slf4j
@Data
public class Person implements InitializingBean, DisposableBean {
    private String name;
    private Integer age;

    public Person() {
        log.info("=====>执行构造方法");
    }

    //对象创建并赋值之后调用
    @PostConstruct
    public void postConstruct() {
        log.info("=====>postConstruct...");
    }

    //容器移除对象之前
    @PreDestroy
    public void preDestroy() {
        log.info("=====>preDestroy...");
    }

    public void init() {
        log.info("=====>init...");
    }

    public void destroy() {
        log.info("=====>destroy...");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        log.info("=====>afterPropertiesSet");
    }
}

执行结果:

1
2
3
4
5
6
00:10:58.851 [main] INFO  com.eh.bean.Person.<init>(Person.java:18) - =====>执行构造方法
00:10:58.857 [main] INFO  com.eh.bean.Person.postConstruct(Person.java:23) - =====>postConstruct...
00:10:58.858 [main] INFO  com.eh.bean.Person.afterPropertiesSet(Person.java:41) - =====>afterPropertiesSet
00:10:58.858 [main] INFO  com.eh.bean.Person.init(Person.java:32) - =====>init...
00:10:58.906 [main] INFO  com.eh.bean.Person.preDestroy(Person.java:28) - =====>preDestroy...
00:10:58.906 [main] INFO  com.eh.bean.Person.destroy(Person.java:36) - =====>destroy...

BeanPostProcessor

后置处理器

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.eh.bean;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

/**
 * 后置处理器:初始化前后进行处理工作
 * 将后置处理器加入到容器中
 */
@Slf4j
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        log.info("postProcessBeforeInitialization..." + beanName);
        return bean;
    }

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

测试结果:

1
2
3
4
5
6
7
8
00:28:36.360 - =====>执行构造方法
00:28:36.363 - postProcessBeforeInitialization...person
00:28:36.363 - =====>postConstruct...
00:28:36.363 - =====>afterPropertiesSet
00:28:36.364 - =====>init...
postProcessAfterInitialization...person
00:28:36.395 - =====>preDestroy...
00:28:36.395 - =====>destroy...

可以看到postProcessBeforeInitialization和postProcessAfterInitialization分别在初始化最前和最后执行

源码分析

  1. 跟到org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean

    1
    2
    3
    4
    
    // 给Bean属性赋值,各种set方法,这里也有后置处理器在工作,后面再讲
    populateBean(beanName, mbd, instanceWrapper);
    // 初始化Bean(调用各种初始化方法)
    exposedObject = initializeBean(beanName, exposedObject, mbd);
    
  2. org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    
    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
      // 先执行postProcessBeforeInitialization方法,在InitDestroyAnnotationBeanPostProcessor这个后置处理器执行postConstruct方法
       wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }
       
    try {
      // 执行init、postProcessAfterInitialization方法
       invokeInitMethods(beanName, wrappedBean, mbd);
    }
    
  3. applyBeanPostProcessorsBeforeInitialization

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    
    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;
    }
    
  4. invokeInitMethods

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    
    protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
          throws Throwable {
    // 执行InitializingBean初始化方法
       boolean isInitializingBean = (bean instanceof InitializingBean);
       if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
          if (logger.isTraceEnabled()) {
             logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
          }
          if (System.getSecurityManager() != null) {
             try {
                AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
                   ((InitializingBean) bean).afterPropertiesSet();
                   return null;
                }, getAccessControlContext());
             }
             catch (PrivilegedActionException pae) {
                throw pae.getException();
             }
          }
          else {
             ((InitializingBean) bean).afterPropertiesSet();
          }
       }
    // 执行init方法
       if (mbd != null && bean.getClass() != NullBean.class) {
          String initMethodName = mbd.getInitMethodName();
          if (StringUtils.hasLength(initMethodName) &&
                !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
                !mbd.isExternallyManagedInitMethod(initMethodName)) {
             invokeCustomInitMethod(beanName, bean, mbd);
          }
       }
    }
    

BeanPostProcessor在spring底层的使用

20201029013050

ApplicationContextAwareProcessor

1
class ApplicationContextAwareProcessor implements BeanPostProcessor {

org.springframework.context.support.ApplicationContextAwareProcessor#invokeAwareInterfaces

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
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) {
     // 这里进行方法回调,所以我们的Bean实现ApplicationContextAware就能将容器注入进来
      ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
   }

BeanValidationPostProcessor

1
public class BeanValidationPostProcessor implements BeanPostProcessor, InitializingBean {
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@Override
public void afterPropertiesSet() {
   if (this.validator == null) {
      this.validator = Validation.buildDefaultValidatorFactory().getValidator();
   }
}


@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
   if (!this.afterInitialization) {
     // 校验工作
      doValidate(bean);
   }
   return bean;
}

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
   if (this.afterInitialization) {
          // 校验工作
      doValidate(bean);
   }
   return bean;
}

InitDestroyAnnotationBeanPostProcessor

调用@PostConstruct和@PreDestroy注解的方法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public void invokeInitMethods(Object target, String beanName) throws Throwable {
   Collection<LifecycleElement> checkedInitMethods = this.checkedInitMethods;
   Collection<LifecycleElement> 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);
      }
   }
}

public void invokeDestroyMethods(Object target, String beanName) throws Throwable {
   Collection<LifecycleElement> checkedDestroyMethods = this.checkedDestroyMethods;
   Collection<LifecycleElement> destroyMethodsToUse =
         (checkedDestroyMethods != null ? checkedDestroyMethods : this.destroyMethods);
   if (!destroyMethodsToUse.isEmpty()) {
      for (LifecycleElement element : destroyMethodsToUse) {
         if (logger.isTraceEnabled()) {
            logger.trace("Invoking destroy method on bean '" + beanName + "': " + element.getMethod());
         }
         element.invoke(target);
      }
   }
}

AutowiredAnnotationBeanPostProcessor

帮我们自动装配bean

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