Spring IoC的Lifecycle

Lifecycle

Lifecycle接口定义Spring容器的生命周期,任何springbean都可以实现该接口。当ApplicationContext接收启动停止信号时,spring容器将在容器上下文中找出所有实现了LifeCycle及其子类接口的类,并一一调用它们实现类对应的方法。

这个接口下面的方法是Spring容器生命周期中的回调方法。Bean也有与之对应的Bean生命周期回调,参考:Bean的生命周期

spring是通过委托给生命周期处理器LifecycleProcessor来实现这一点的。

image-20191118232109129

LifecycleProcessor继承于Lifecycle接口,新增了刷新和关闭方法。

AbstractApplicationContext中Lifecycle的处理逻辑

AbstractApplicationContext关联了LifecycleProcessor,在其refresh的最后finishRefresh方法里面调用到了onRefresh方法触发Lifecyclestart方法:

1
2
// Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh();

注意,这里只会刷新SmartLifecycle的子类,具体处理逻辑如下:

1
2
3
4
5
6
private void startBeans(boolean autoStartupOnly) {
Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
Map<Integer, LifecycleGroup> phases = new HashMap<>();
lifecycleBeans.forEach((beanName, bean) -> {
if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
...

onRefresh方法传入了autoStartupOnly=true,而SmartLifecycle的isAutoStartup方法默认返回true,故默认情况下会处理SmartLifecycle的子类。

针对Lifecycle的子类,需要自己手动调用ApplicationContext的start或者stop方法来触发具体bean的生命周期实现。

Lifecycle使用例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Service
public class TestLifeCycle implements Lifecycle {

private volatile boolean running = false;

@Override
public void start() {
System.out.println("==== start");
running = true;
}

@Override
public void stop() {
System.out.println("==== stop");
running = false;
}

@Override
public boolean isRunning() {
return running;
}

}
1
2
3
4
5
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
applicationContext.start();
applicationContext.close();
}

References

通过源码查看Spring SmartLifecycle 的执行顺序

玩转Spring(1) Spring生命周期之Lifecycle

arthinking wechat
欢迎关注itzhai公众号
  • 本文作者: arthinking
  • 本文链接: spring-ioc-lifecycle.html
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!