s

steakliu

V1

2022/06/26阅读:31主题:萌绿

被隔离了,聊一聊春(Spring)的生命周期

码农在囧途

从北京回成都被隔离7天,今天是第二天,我是一个比较自由的人,如果让我宅在屋子里面,我真的会疯掉,我总是盯着窗外看,不由自主地想到钱钟书在《围城》里面说:婚姻是一座围城,城外的人想进去,城里的人想出来,虽然我没有婚姻,不过以我目前被隔离地状态,我是能理解那种感受的,我想到,看到身边不少的男性女性朋友步入婚姻后,有的幸福,有的是无比的痛苦,不过,你在选择的时候,就要想清楚你是否能承担这个选择给你带来的后果,任何事物都是这样,不论婚姻,学业,事业,爱情等,美好的事物可能会伴随不好的结果,同样,不好的开端同样可能会收获完美的结局,这一切都取决于我们怎么抉择,如果你喜欢城外,那么就呆在城外,你喜欢城里,那么就呆在城里!

前言

今天我们来分享一下Spring Bean的生命周期,Spring Bean的生命周期对于我们掌握Spring来说事很关键的,理解了Spring的生命周期,那么我们在开发的时候才能更好的利用Spring的功能,从而达到我们的目的!

Spring Bean的生命周期图

1.Bean元信息配置

此阶段主要配置bean的信息,bean的配置有xml,注解,properties,API BeanDefinition方式,我们主要用的是xml和注解,不过随着 springboot的发展,现在xml也不怎么用了,一般都是使用注解,不过这些方式最终都会通过解析,然后配置到BeanDefinition中,所以我们可以直接 通过原生API BeanDefinition来创建Bean,下面我们主要通过xml和注解来配置简单的Bean。

定义一个Bean

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private String username;
    private String idCard;
}

XML方式

构造注入

<bean id="user" class="com.steak.spring.beanbuild.User">
    <constructor-arg index="0" name="username" value="steak"/>
    <constructor-arg index="1" name="idCard" value="522425199812290589"/>
</bean>

set注入

<bean id="user" class="com.steak.spring.beanbuild.User">
    <property name="username" value="steak"/>
    <property name="idCard" value="522425199812290589"/>
</bean>

注解方式

使用@Configuration@Bean

@Configuration
public class UserConfig {

    @Bean
    public User user(){
        return new User("steak","123456");
    }
}

使用@Component@Service,@Controller等注解申明一个Bean

@Component
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private String username;
    private String idCard;
}

使用BeanDefinition直接配置一个Bean

使用BeanDefinitionBuilder建造者来构建一个Bean,并设置属性和其他一些信息,如作用域scope,懒加载lazyInit等,使用addPropertyValue 来填充属性,构建完成之后使用DefaultListableBeanFactoryregisterBeanDefinition注册到Spring工厂。

public class BeanBuildTest {
    public static void main(String[] args) {
        //构建BeanDefinition
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(User.class.getName());
        beanDefinitionBuilder.addPropertyValue("username","steak");
        beanDefinitionBuilder.addPropertyValue("idCard","522425199812290045");
        AbstractBeanDefinition userBeanDefinition = beanDefinitionBuilder.getBeanDefinition();
        System.out.println(userBeanDefinition);

        //注册Bean
        DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();
        defaultListableBeanFactory.registerBeanDefinition("user",userBeanDefinition);
        
        //获取Bean
        User user = defaultListableBeanFactory.getBean("user", User.class);
        System.out.println(user);
    }
}

2.Bean元信息解析阶段

第二阶段主要是解析Bean的元信息,这里我们主要来演示解析XML注解方式的Bean,

解析XML

使用XmlBeanDefinitionReader来对xml文件进行解析,loadBeanDefinitions加载spring配置文件,这个方法返回参数是一个整数, 代表Bean的个数,然后使用DefaultListableBeanFactorygetBeanDefinitionNames获取所有Bean,返回一个数组,我们再对其解析。

public class XmlBeanReaderTest {
    public static void main(String[] args) {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
        xmlBeanDefinitionReader.loadBeanDefinitions("spring.xml");
        String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
        for (String definitionName : beanDefinitionNames) {
            BeanDefinition beanDefinition = beanFactory.getBeanDefinition(definitionName);
            System.out.println(beanDefinition.getPropertyValues());
            System.out.println(definitionName);
        }
    }
}

解析注解

注解使用AnnotatedBeanDefinitionReader对Bean进行解析

public class AnnotationBeanReaderTest {
    public static void main(String[] args) {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(beanFactory);
        reader.register(UserService.class);
        BeanDefinition beanDefinition = beanFactory.getBeanDefinition("userService");
        System.out.println(beanDefinition);
    }
}

3.将Bean注册到Spring容器中

解析完Bean以后,需要将Bean注册到Spring容器中,注册Bean有一个接口BeanDefinitionRegistry,它继承了AliasRegistry接口,可以看出它提供了设置别名 的一些操作,BeanDefinitionRegistry是一个接口,我们不能直接进行实例化,所以我们一般使用的是它的实现类DefaultListableBeanFactory

BeanDefinitionRegistry

public interface BeanDefinitionRegistry extends AliasRegistry {
    void registerBeanDefinition(String var1, BeanDefinition var2) throws BeanDefinitionStoreException;

    void removeBeanDefinition(String var1) throws NoSuchBeanDefinitionException;

    BeanDefinition getBeanDefinition(String var1) throws NoSuchBeanDefinitionException;

    boolean containsBeanDefinition(String var1);

    String[] getBeanDefinitionNames();

    int getBeanDefinitionCount();

    boolean isBeanNameInUse(String var1);
}

AliasRegistry

public interface AliasRegistry {
    //设置别名
    void registerAlias(String name, String alias);
    //移除别名
    void removeAlias(String alias);
    //是否是别名
    boolean isAlias(String name);
    //获取别名
    String[] getAliases(String name);
}

注册Bean

注册Bean需要使用一个BeanDefinitionBuilder建造者来建造一个BeanDefinition,上面已经说过,这里不赘述。建造完成以后再使用BeanDefinitionRegistry 来注册Bean,使用registerBeanDefinition进行注册。

public class BeanRegister {
    public static void main(String[] args) {
        //构建BeanDefinition
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(User.class.getName());
        beanDefinitionBuilder.addPropertyValue("username","steak");
        beanDefinitionBuilder.addPropertyValue("idCard","522425199812290045");
        AbstractBeanDefinition userBeanDefinition = beanDefinitionBuilder.getBeanDefinition();
        System.out.println(userBeanDefinition);

        //注册Bean到Spring
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        beanFactory.registerBeanDefinition("user",userBeanDefinition);

        //获取Bean
        User user = beanFactory.getBean("user", User.class);
        System.out.println(user);
    }
}

为Bean设置别名,因为BeanDefinitionRegistry继承了AliasRegistry,AliasRegistry提供了一些操作别名的方法,下面演示一些方法。

设置别名,获取别名
beanFactory.registerBeanDefinition("user",userBeanDefinition);
beanFactory.registerAlias("user","user-1");
beanFactory.registerAlias("user","user-2");
//获取Bean
User user = beanFactory.getBean("user", User.class);
for (String alias : beanFactory.getAliases("user")) {
    System.out.println(alias);
}

到这里Spring的Bean就注册完了,注册完Bean以后再继续做其他的操作。

4.Bean实例化

Bean实例化分为实例化前和实例化,实例化前会调用applyBeanPostProcessorsBeforeInitialization, 实例化会调用determineConstructorsFromBeanPostProcessors

applyBeanPostProcessorsBeforeInitialization实例化前操作

 @Override
 public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
   throws BeansException 
{
  Object result = existingBean;
  for (BeanPostProcessor processor : getBeanPostProcessors()) {
   Object current = processor.postProcessBeforeInitialization(result, beanName);
   if (current == null) {
    return result;
   }
   result = current;
  }
  return result;
 }

看出对getBeanPostProcessors()进行遍历操作,getBeanPostProcessors()是一个集合,泛型是BeanPostProcessor,BeanPostProcessor可以使我们 在对Bean进行实例化的时候做一些干扰,

private final List<BeanPostProcessor> beanPostProcessors = new BeanPostProcessorCacheAwareList();

对Bean实例化进行干扰

public class BeanInstanceBeforeTest{
    public static void main(String[] args) {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        beanFactory.addBeanPostProcessor(new BeanPostProcessor() {
            @Override
            public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
                if ("user".equals(beanName)){
                    return new User("liupai","123456");
                }
                return null;
            }
        });

        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class)
                .addPropertyValue("idCard", "111111")
                .addPropertyValue("username", "steak")
                .getBeanDefinition()
;
        beanFactory.registerBeanDefinition("user",beanDefinition);
        User user = beanFactory.getBean("user", User.class);
        System.out.println(user);
    }
}

在实例化前我们对Bean进行干扰,如果Bean为"user",那么对其重新赋值,我们从输出可以看出输出的并不是我们使用BeanDefinitionBuilder.addPropertyValue() 构造的值,而是在BeanPostProcessor构造的值,由此可以看出实例化过程已经被我们干扰,不过这样的操作一般不会用。

实例化

通过Bean的构造函数实例化Bean

 @Nullable
 protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
   throws BeansException {

  if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
   for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
    Constructor<?>[] ctors = bp.determineCandidateConstructors(beanClass, beanName);
    if (ctors != null) {
     return ctors;
    }
   }
  }
  return null;
 }

实例化后

Bean实例化完成后会调用applyBeanPostProcessorsAfterInitialization方法

    @Override
 public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
   throws BeansException 
{

  Object result = existingBean;
  for (BeanPostProcessor processor : getBeanPostProcessors()) {
   Object current = processor.postProcessAfterInitialization(result, beanName);
   if (current == null) {
    return result;
   }
   result = current;
  }
  return result;
 }

我们也可以对实例化后的Bean进行干扰,下面我们将实例化后的Bean设置为空

public class BeanInstanceAfterTest{
    public static void main(String[] args) {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        beanFactory.addBeanPostProcessor(new BeanPostProcessor() {
            @Override
            public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
               if (beanName.equals("user")){
                   return new User(null,null);
               }
                return null;
            }
        });

        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class)
                .addPropertyValue("idCard", "111111")
                .addPropertyValue("username", "steak")
                .getBeanDefinition()
;
        beanFactory.registerBeanDefinition("user",beanDefinition);
        User user = beanFactory.getBean("user", User.class);
        System.out.println(user);
    }
}

从输出结果可以看出我们在实例化Bean以后可以对其进行干扰,只不过这样的操作很少会去用。

5.属性赋值

对Bean进行实例化后就到了属性赋值阶段,属性赋值阶段会调用InstantiationAwareBeanPostProcessorpostProcessProperties,下面我们手动进行属性赋值, 我们在构建 BeanDefinition时并没有设置属性,而是在进行实例化的时候再进行属性赋值,

public class BeanPropertiesTest {
    public static void main(String[] args) {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        beanFactory.addBeanPostProcessor(new InstantiationAwareBeanPostProcessor() {
            @Override
            public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
               if (beanName.equals("user")){
                   MutablePropertyValues propertyValues = (MutablePropertyValues) pvs;
                   propertyValues.add("username","steak");
                   propertyValues.add("idCard","111111");
               }
               return null;
            }
        });

        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class)
                .getBeanDefinition()
;
        beanFactory.registerBeanDefinition("user",beanDefinition);
        User user = beanFactory.getBean("user", User.class);
        System.out.println(user);
    }
}

从输出可以看出属性设置成功。

如果在构建BeanDefinition的时候已经有属性值了,那么PropertyValues就会有相应的属性值(这些属性值是我们在XML或者注解中设置的值)

public class BeanPropertiesTest {
    public static void main(String[] args) {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        beanFactory.addBeanPostProcessor(new InstantiationAwareBeanPostProcessor() {
            @Override
            public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
               return null;
            }
        });

        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class)
                .addPropertyValue("idCard", "222222")
                .addPropertyValue("username", "steak")
                .getBeanDefinition()
;
        beanFactory.registerBeanDefinition("user",beanDefinition);
        User user = beanFactory.getBean("user", User.class);
        System.out.println(user);
    }
}

6.Bean初始化

Bean Aware接口回调

Bean属性赋值成功以后会回调invokeAwareMethods,实现BeanNameAware , BeanClassLoaderAware , BeanFactoryAware接口的Bean,在Bean 初始化的时候会依次执行,如下。

实现BeanNameAware , BeanClassLoaderAware , BeanFactoryAware的Bean

public class UserAware implements BeanNameAware , BeanClassLoaderAware , BeanFactoryAware  {
    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        System.out.println("classLoader  "+classLoader);
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("beanFactory   "+beanFactory);
    }

    @Override
    public void setBeanName(String name) {
        System.out.println("name  "+name);
    }
}

测试Bean

public class UserAwareTest {
    public static void main(String[] args) {
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(UserAware.class.getName());
        AbstractBeanDefinition userBeanDefinition = beanDefinitionBuilder.getBeanDefinition();

        //注册Bean
        DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();
        defaultListableBeanFactory.registerBeanDefinition("userAware",userBeanDefinition);

        //获取Bean
        UserAware userAware = defaultListableBeanFactory.getBean("userAware", UserAware.class);
        System.out.println(userAware);
    }
}

由此看出,执行顺序是按照回调函数invokeAwareMethods的Bean判断顺序来执行的,顺序为BeanNameAware->BeanClassLoaderAware->BeanFactoryAware

Bean初始化前

Bean初始化前会调用BeanPostProcessor接口的postProcessBeforeInitialization作初始化操作,BeanPostProcessor, 看下BeanPostProcessor的两个实现类 CommonAnnotationBeanPostProcessorApplicationContextAwareProcessor

ApplicationContextAwareProcessorinvokeAwareInterfaces中有7个判断,如果我们的Bean实现了这7个Aware接口,那么将会依次执行这 7个接口的方法,CommonAnnotationBeanPostProcessor是处理@PostConstruct的处理器

ApplicationContextAwareProcessor

    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 ApplicationStartupAware) {
   ((ApplicationStartupAware) bean).setApplicationStartup(this.applicationContext.getApplicationStartup());
  }
  if (bean instanceof ApplicationContextAware) {
   ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
  }
 }

CommonAnnotationBeanPostProcessor

public CommonAnnotationBeanPostProcessor(){
        setOrder(Ordered.LOWEST_PRECEDENCE-3);
        setInitAnnotationType(PostConstruct.class);
        setDestroyAnnotationType(PreDestroy.class);
        ignoreResourceType("javax.xml.ws.WebServiceContext");

        // java.naming module present on JDK 9+?
        if(jndiPresent){
        this.jndiFactory=new SimpleJndiBeanFactory();
        }
}

实现7个Aware接口和编写一个@PostConstruct注解的方法

public class UserApplicationContextAware implements EnvironmentAware , EmbeddedValueResolverAware , ResourceLoaderAware,
        ApplicationEventPublisherAwareMessageSourceAware,ApplicationStartupAware,ApplicationContextAware 
{
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("applicationContext  "+applicationContext);
    }
    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        System.out.println("applicationEventPublisher  "+applicationEventPublisher);
    }
    @Override
    public void setApplicationStartup(ApplicationStartup applicationStartup) {
        System.out.println("applicationStartup  "+applicationStartup);
    }
    @Override
    public void setEmbeddedValueResolver(StringValueResolver resolver) {
        System.out.println("resolver  "+resolver);
    }
    @Override
    public void setEnvironment(Environment environment) {
        System.out.println("environment  "+environment);
    }
    @Override
    public void setMessageSource(MessageSource messageSource) {
        System.out.println("messageSource  "+messageSource);
    }
    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        System.out.println("resourceLoader  "+resourceLoader);
    }
    @PostConstruct
    public void PostConstructTest(){
        System.out.println("PostConstruct SimpleTest");
    }
}

测试

public class UserApplicationContextAwareTest {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.register(UserApplicationContextAware.class);
        context.refresh();
    }
}

可以看出实现了EnvironmentAware , EmbeddedValueResolverAware , ResourceLoaderAware, ApplicationEventPublisherAware, MessageSourceAware,ApplicationStartupAware,ApplicationContextAware这七个接口,将会按照ApplicationContextAwareProcessorinvokeAwareInterfaces顺序执行

Bean初始化

Bean在初始化的时候会调用InitializingBean接口的afterPropertiesSet()方法。

public interface InitializingBean {
 void afterPropertiesSet() throws Exception;
}

如果我们指定了Bean的初始化方法,那么在调用完afterPropertiesSet()方法后会调用我们自定义的初始化方法

定义一个Bean并实现InitializingBean

public class BusinessService implements InitializingBean {
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("after ");
    }
    /**
     * 初始化方法
     */

    public void init(){
        System.out.println("init");
    }
}

配置Bean并设置初始化方法

可以通过@Bean(initMethod = "init")这种方式来设置Bean的初始化方法,这个方法就是BusinessServiceBean中的 init()方法,

@Configuration
public class BeanConfig{

    @Bean(initMethod = "init")
    public BusinessService businessService(){
        return new BusinessService();
    }
}

测试

public class ConfigBeanTest {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class);
    }
}

从输出看出先执行afterPropertiesSet()在执行我们自定义的初始化方法。

Bean初始化后

Bean初始化完成后会调用BeanPostProcessor接口的postProcessAfterInitialization()方法。

7.Bean初始化完成后阶段

所有单例Bean初始化完成之后会调用SmartInitializingSingleton接口的afterSingletonsInstantiated()方法,逻辑如下

    for (String beanName : beanNames) {
   Object singletonInstance = getSingleton(beanName);
   if (singletonInstance instanceof SmartInitializingSingleton) {
    StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
      .tag("beanName", beanName);
    SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
    if (System.getSecurityManager() != null) {
     AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
      smartSingleton.afterSingletonsInstantiated();
      return null;
     }, getAccessControlContext());
    }
    else {
     smartSingleton.afterSingletonsInstantiated();
    }
    smartInitialize.end();
   }
  }

Bean1

public class Bean1 {
    public Bean1(){
        System.out.println("bean1  ");
    }
}

Bean2

public class Bean2 {
    public Bean2(){
        System.out.println("bean2");
    }
}

BeanInitOverConfig实现SmartInitializingSingleton

@Configuration
public class BeanInitOverConfig implements SmartInitializingSingleton {
    @Override
    public void afterSingletonsInstantiated() {
        System.out.println("所有单例bean初始化完成之后调用");
    }
    @Bean
    public Bean1 bean1(){
        return new Bean1();
    }
    @Bean
    public Bean2 bean2(){
        return new Bean2();
    }
}

测试

public class BeanInitOverTest {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanInitOverConfig.class);
    }
}

从输出可以看出Bean1和Bean2输出后afterSingletonsInstantiated()再输出,由此证明所有单例Bean初始化完成后会调用SmartInitializingSingletonafterSingletonsInstantiated()方法。

8.使用Bean

初始化完成Bean后就可以使用Bean,使用Bean使用getBean方法便可,

public class BeanInitOverTest {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanInitOverConfig.class);
        Bean1 bean1 = context.getBean("bean1", Bean1.class);
    }
}

9.销毁Bean

Bean的销毁可以使用@PreDestroy注解,自定义销毁方法,实现DisposableBean接口。

定义一个Bean,并使用三种销毁bean的方式

public class Bean1 implements DisposableBean {
    public Bean1(){
        System.out.println("bean1  ");
    }
    /**
     * 自定义销毁方法
     */

    public void bean1Destroy(){
        System.out.println("销毁bean1");
    }
    /**
     * 实现DisposableBean
     * @throws Exception
     */

    @Override
    public void destroy() throws Exception {
        System.out.println("继承DisposableBean销毁bean");
    }
    /**
     * 使用@PreDestroy
     */

    @PreDestroy
    public void preDestroy(){
        System.out.println("@PreDestroy销毁bean");
    }
}

Bean配置类,指定自定义销毁方法

@Configuration
public class BeanDestroyConfig{

    @Bean(destroyMethod = "bean1Destroy")
    public Bean1 bean1(){
        return new Bean1();
    }
}

测试,使用AnnotationConfigApplicationContextclose触发销毁bean

public class BeanDestroyTest {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanDestroyConfig.class);
        context.close();
    }
}

可以看出使用销毁顺序优先级为@PreDestroy > 实现DisposableBean > 自定义方法

使用@PreDestroy销毁Bean,它会调用DestructionAwareBeanPostProcessorpostProcessBeforeDestruction,postProcessBeforeDestruction 在它的实现类InitDestroyAnnotationBeanPostProcessor中进行销毁

@Override
 public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
  LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
  try {
   metadata.invokeDestroyMethods(bean, beanName);
  }
  catch (InvocationTargetException ex) {
   String msg = "Destroy method on bean with name '" + beanName + "' threw an exception";
   if (logger.isDebugEnabled()) {
    logger.warn(msg, ex.getTargetException());
   }
   else {
    logger.warn(msg + ": " + ex.getTargetException());
   }
  }
  catch (Throwable ex) {
   logger.warn("Failed to invoke destroy method on bean with name '" + beanName + "'", ex);
  }
 }

CommonAnnotationBeanPostProcessor@PreDestroy进行管理,它继承了InitDestroyAnnotationBeanPostProcessor

到这里,Bean的生命周期就说完了。

今天的分享就到这里,感谢你的观看,我们下期见

分类:

后端

标签:

后端

作者介绍

s
steakliu
V1