服务器之家

服务器之家 > 正文

Spring与bean有关的生命周期示例详解

时间:2020-07-27 12:55     来源/作者:eaglelihh

前言

记得以前的时候,每次提起Spring中的bean相关的生命周期时,内心都无比的恐惧,因为好像有很多,自己又理不清楚:什么beanFactory啊,aware接口啊,beanPostProcessor啊,afterPropertiesSet啊,initMethod啊等等。

今天终于理清这些关系了,并且又新增了对postConstruct和lifecycle的理解。

执行顺序

- 首先是 BeanFactoryPostProcessor,它是针对所有bean的definition的,只执行一次

下面是针对每个bean的初始

  • - 实现了一系列aware接口的,比如BeanNameAware,ApplicationContextAware,调用其set方法
  • - 执行BeanPostProcessor的postProcessBeforeInitialization方法
  • - 带有@PostConstruct注解的方法
  • - 实现InitializingBean接口的afterPropertiesSet方法
  • - 指定的initMethod方法
  • - 执行BeanPostProcessor的postProcessAfterInitialization方法
  • - 实现了SmartLifecycle接口的start方法(实现Lifecycle接口的不会自动调用,需要显式的调用start方法)

下面是针对每个bean的销毁

  • - 实现了SmartLifecycle接口的stop方法(实现Lifecycle接口的不会自动调用,需要显式的调用stop方法)
  • - 带有@PreDestroy注解的方法
  • - 实现DisposableBean接口的destroy方法
  • - 指定的destroyMethod方法

目前就想到这么多了,其他的麻烦在评论区留言呀~

代码实例

bean实体类

?
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/**
 * @date: 2020-07-22
 *
 * 一个简单的枚举类
 */
public enum BeanType {
  NORMAL, LIFECYCLE, SMART_LIFECYCLE;
}
 
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/**
 * @author: lihui
 * @date: 2020-07-22
 * 一个简单的bean
 */
@Slf4j
public class NormalBean implements BeanNameAware, ApplicationContextAware, InitializingBean, DisposableBean {
  private BeanType beanType;
 
  public NormalBean() {
    this(BeanType.NORMAL);
  }
 
  public NormalBean(BeanType beanType) {
    this.beanType = beanType;
  }
 
  @PostConstruct
  public void postConstruct() {
    log.info("{}, postConstruct", beanType);
  }
 
  @Override
  public void afterPropertiesSet() throws Exception {
    log.info("{}, afterPropertiesSet", beanType);
  }
 
  public void initMethod() {
    log.info("{}, initMethod", beanType);
  }
 
  @PreDestroy
  public void preDestroy() {
    log.info("{}, preDestroy", beanType);
  }
 
  @Override
  public void destroy() throws Exception {
    log.info("{}, destroy", beanType);
  }
 
  public void destroyMethod() {
    log.info("{}, destroyMethod", beanType);
  }
 
  @Override
  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    log.info("setApplicationContext, applicationContext : {}", applicationContext);
  }
 
  @Override
  public void setBeanName(String name) {
    log.info("setBeanName, bean name : {}", name);
  }
}
 
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.Lifecycle;
/**
 * @author: lihui
 * @date: 2020-07-22
 * 实现了Lifecycle的一个bean
 */
@Slf4j
public class LifecycleBean extends NormalBean implements Lifecycle {
  private volatile boolean running = false;
 
  public LifecycleBean() {
    super(BeanType.LIFECYCLE);
  }
 
  @Override
  public void start() {
    log.info("start");
    running = true;
  }
 
  @Override
  public void stop() {
    log.info("stop");
    running = false;
  }
 
  @Override
  public boolean isRunning() {
    return running;
  }
}
 
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.SmartLifecycle;
/**
 * @author: lihui
 * @date: 2020-07-22
 * 实现了SmartLifecycle的一个bean
 */
@Slf4j
public class SmartLifecycleBean extends NormalBean implements SmartLifecycle {
  private volatile boolean running = false;
 
  public SmartLifecycleBean() {
    super(BeanType.SMART_LIFECYCLE);
  }
 
  @Override
  public void start() {
    log.info("start");
    running = true;
  }
 
  @Override
  public void stop() {
    log.info("stop");
    running = false;
  }
 
  @Override
  public boolean isRunning() {
    return running;
  }
}

配置类

?
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
/**
 * @author: lihui
 * @date: 2020-07-25
 */
@Slf4j
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
  @Override
  public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    log.info("postProcessBeanFactory, beanFactory:{}", beanFactory);
  }
}
 
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
 * @author: lihui
 * @date: 2020-07-25
 */
@Slf4j
public class MyBeanPostProcessor implements BeanPostProcessor {
  @Override
  public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    log.info("postProcessBeforeInitialization, bean:{}", beanName);
    return bean;
  }
 
  @Override
  public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    log.info("postProcessAfterInitialization, bean:{}", beanName);
    return bean;
  }
}
 
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.SmartLifecycle;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
 * @author: lihui
 * @date: 2020-07-22
 */
@Configuration
@Slf4j
public class Config {
 
  @Bean(initMethod = "initMethod", destroyMethod = "destroyMethod")
  public NormalBean normalBean() {
    return new NormalBean();
  }
 
  @Bean(initMethod = "initMethod", destroyMethod = "destroyMethod")
  public LifecycleBean lifecycleBean() {
    return new LifecycleBean();
  }
 
  @Bean(initMethod = "initMethod", destroyMethod = "destroyMethod")
  public SmartLifecycle smartLifecycle() {
    return new SmartLifecycleBean();
  }
 
  @Bean
  public static MyBeanFactoryPostProcessor myBeanFactoryPostProcessor() {
    return new MyBeanFactoryPostProcessor();
  }
 
  @Bean
  public static MyBeanPostProcessor myBeanPostProcessor() {
    return new MyBeanPostProcessor();
  }
}

Main类

?
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.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 
/**
 * @author: lihui
 * @date: 2020-07-22
 */
@Slf4j
public class Main {
  public static void main(String[] args) throws InterruptedException {
    ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class);
    ctx.registerShutdownHook();
    Thread.sleep(5000);
    log.info("line ----------------------------- line");
    ctx.start();
    ctx.stop();
    log.info("line ----------------------------- line");
  }
}

结果说明

结果正如前面所说的执行顺序一致,主要注意的就是Lifecycle接口和SmartLifecycle接口,只有实现了SmartLifecycle接口的bean在初始化时才会被自动调用,而实现了Lifecycle接口的除非显式调用start和stop方法才会被调用。

总结

到此这篇关于Spring与bean有关的生命周期的文章就介绍到这了,更多相关Spring与bean生命周期内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://www.cnblogs.com/eaglelihh/p/13383039.html

标签:

相关文章

热门资讯

2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
歪歪漫画vip账号共享2020_yy漫画免费账号密码共享
歪歪漫画vip账号共享2020_yy漫画免费账号密码共享 2020-04-07
Intellij idea2020永久破解,亲测可用!!!
Intellij idea2020永久破解,亲测可用!!! 2020-05-20
男生常说24816是什么意思?女生说13579是什么意思?
男生常说24816是什么意思?女生说13579是什么意思? 2019-09-17
沙雕群名称大全2019精选 今年最火的微信群名沙雕有创意
沙雕群名称大全2019精选 今年最火的微信群名沙雕有创意 2019-07-07
返回顶部