0%

SpringBoot Bean生命周期的Hook

这里介绍在SpringBoot Bean生命周期当中常用的Hook

abstract.png

Bean实例化时的Hook

Spring Boot Bean在实例化时常用的Hook有:

  • @PostConstruct注解
  • InitializingBean接口的afterPropertiesSet方法
  • @Bean注解的initMethod属性

调用顺序依次为:@PostConstruct注解标记的方法 -> InitializingBean接口的afterPropertiesSet方法 -> @Bean注解中initMethod属性指定的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import org.springframework.beans.factory.InitializingBean;
import javax.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class Dog implements InitializingBean {
public void hello() {
log.info("call by hook: @PostConstruct");
}

@Override
public void afterPropertiesSet() throws Exception {
log.info("call by hook: afterPropertiesSet of InitializingBean");
}

public void hi() {
log.info("call by hook: initMethod of @Bean");
}
}
1
2
3
4
5
6
7
8
9
10
11
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class DogConfig {

@Bean(initMethod = "hi")
public Dog dog() {
return new Dog();
}
}

figure 1.png

特别地,BeanPostProcessor接口则可用于拦截所有Bean的实例化。具体地:

  • postProcessBeforeInitialization方法:该方法会在调用Bean的初始化方法之前被调用
  • postProcessAfterInitialization方法:该方法会在调用Bean的初始化方法之后被调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class MyCustomBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
log.info("exec before method, bean name: {}", beanName);
return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
}

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
log.info("exec after method, bean name {}", beanName);
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
}

figure 2.png

Bean销毁时的Hook

Spring Boot Bean在销毁时常用的Hook有:

  • @PreDestroy注解
  • DisposableBean接口的destroy方法
  • @Bean注解的destroyMethod属性

调用顺序依次为:@PreDestroy注解注解标记的方法 -> DisposableBean接口的destroy方法 -> @Bean注解中destroyMethod属性指定的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.DisposableBean;
import javax.annotation.PreDestroy;

@Slf4j
public class Male implements DisposableBean {

@PreDestroy
public void gg() {
log.info("call by hook: @PreDestroy");
}

@Override
public void destroy() throws Exception {
log.info("call by hook: destroy of DisposableBean");
}

public void bye() {
log.info("call by hook: destroyMethod of @Bean");
}

}
1
2
3
4
5
6
7
8
9
10
11
12
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MaleConfig {

@Bean(destroyMethod = "bye")
public Male male() {
return new Male();
}

}

figure 3.png

Note: 利用@Bean注解创建实例时需要注意,@Bean注解存在 销毁方法推断 的行为。即如果没有显式设置destroyMethod属性时,其会将public公共的、无参的、命名为close或shutdown的方法 自动注册为该Bean的销毁方法。如果需要禁用某个@Bean注解的 销毁方法推断 行为,可以将destroyMethod属性显式设置为””空字符串

请我喝杯咖啡捏~

欢迎关注我的微信公众号:青灯抽丝