Spring-Lifecycle分析
简介
Lifecycle接口在项目中看到过一眼,之前都不知道这个。这篇文章就来介绍介绍他。
从类图看出,主要有三个接口,最主要的有Lifecycle和SmartLifecycle接口。
首先要知道,Lifecycle
接口的语义就是启动停止。所以,实现他的类,都是需要启动和停止的类,并且SmartLifecycle在他的语义上面,增加了Pahsed
(我觉得分组更适合),和自动启动的功能。
功能
-
Lifecycle
它是一个通用的接口,主要用于生命周期的控制操作。定义了start/stop的方法。可以被bean和容器实现,如果是容器实现的话,容器会传播一个信号,应用给容器中所有的实现了这个接口的bean。
需要注意,这个接口里面的start方法是需要手动调用的。没有自动启动的含义(自动启动就是在容器启动了之后,容器会自动调用)。
-
SmartLifecycle
扩展了Lifecycle。主要是用于需要在 ApplicationContext 启动自动启动语义的bean。
-
Phased
阶段对象,提供了一个
int getPhase();
,接口是用来表示功能的,那么这个接口就用来表示阶段(我觉得分组更加的适合把)。
区别
Lifecycle接口
用来表示生命周期,提供了两个方法(start/stop),用来启动和停止。isRunning方法表示当前是否已经启动。(这个接口没有自动启动的意思,如果要启动,就需要手动启动,停止是在ApplicationContext关闭的时候会调用)。
如果已经启动,再次调用的话,不应该就要抛出异常了。
如果是容器实现了这个接口(比如ConfigurableApplicationContext),容器会唤醒所有的实现了这个接口的组件。
如果已经停止,再次调用,也不应该抛出异常。
isRuning方法返回是否运行,对于容器来说,当他里面所有的component都停止了,才会返回ture。
public interface Lifecycle {
void start();
void stop();
boolean isRunning();
}
SmartLifecycle接口
拓展了Lifecycle接口,增加了自动启动的功能,这个功能主要是在ApplicationContext refresh的时候会自动启动。
此外还增了对异步停止的支持,自动了了一个stop(Runnable calllback)
方法,主要是给DefaultLifecycleProcessor来做调用的。
public interface SmartLifecycle extends Lifecycle, Phased {
// 默认的阶段
int DEFAULT_PHASE = Integer.MAX_VALUE;
// 是否要自动启动,注意,这个default关键词。
default boolean isAutoStartup() {
return true;
}
/**
停止在运行的Lifecycle component。要注意,他提供了一个回调方法用于,支持顺序和并发,给LifecycleProcessor使用。回调方法必须是在内部的stop方法调用完了之后,才调用这个
*/
default void stop(Runnable callback) {
stop();
callback.run();
}
// 返回所处的阶段。有默认值。
@Override
default int getPhase() {
return DEFAULT_PHASE;
}
}
上面分析了两个接口的主要功能,下面分析这些接口是在哪里调用的。
解析
在LifeCycle中,还有一个需要关注的实现类。
看这个名字基本能猜到,这就是用来处理,Lifecycle的。除了传统的Aware接口之外,LifecycleProcessor还增加了onRefresh/onClose
方法。这两是用于context刷新的close时候的通知。对于DefaultLifecycleProcessor来说,在这俩方法里面就可以做自动启动和停止所有的Cyclelife的Component。
具体的做法
-
start方法
-
从beanFactory中获取所有实现实现了Lifecycle接口的bean。
-
增加了对SmartLifecycle的处理(是否自动启动)
-
此外还增加对Phased接口的处理,SmartLifeCycly实现了这个接口,如果没有实现默认的是就是0.
-
针对Phased接口分组,排序,将同一个Phased的bean放在一个LifecycleGroup里面。
-
封装成LifecycleGroup之后,因为LifecycleGroup里面是一组lifecycle的集合,所以,调用LifecycleGroup的start方法就是循环调 用LifecycleGroup里面集合的lifecycle的start方法。并且在LifecycleGroup里面记录了smartLifecycle的数量。
-
在调用之前,先调用当前bean依赖的bean的start方法。
-
在调用的时候增加了对自动启动和的支持。
到这里,start方法就结束了。
-
-
stop方法
-
从beanFactory中获取所有实现实现了Lifecycle接口的bean。
-
此外还增加对Phased接口的处理,SmartLifeCycly实现了这个接口,如果没有实现默认的是就是0.
-
针对Phased接口分组,排序,将同一个Phased的bean放在一个LifecycleGroup里面。
-
按照Phased的大小排序,倒叙。
-
封装成LifecycleGroup。然后循环调用。这里的调用得展开说说了
-
会通过smartLifecycle的数量,创建一个CountDownLatch。并且在创建一个线程安全的Set。
-
先调用当前bean依赖的bean的stop方法。
-
如果当前的bean 在运行,(Lifecycle#isRunning的返回值)
-
如果是smartLifecycle,就会将调用smartLifecycle的stop方法,并且传递一个callBack的Runnable。
在这个callback里面主要是下面的代码
((SmartLifecycle) bean).stop(() -> { // 利用countdown来做同步, latch.countDown(); // 将之前添加到countDownBeanNames里面的bean移除掉。 countDownBeanNames.remove(beanName); if (logger.isDebugEnabled()) { logger.debug("Bean '" + beanName + "' completed its stop procedure"); } });
-
如果不是,直接调用Lifecycle的stop方法,
-
-
循环调用结束之后,直接调用
latch.await(this.timeout, TimeUnit.MILLISECONDS);
等待,刚才的同步操作。
-
问题?
-
同步怎么用?
如果不实现
stop(Runnable callback)
方法,这个同步是没有意义的。必须要重写这个方法。才能使countdownLatch起作用,并且countdownLatch在异步的环境下才有作用,如果在一个单线程的话,这个是没有什么意义的。 -
这里为啥要有这个同步的操作。
需要同步,就说明可能会有异步的操作,那么对于一个框架来说,提供的功能应该全面。此外,smartLifecycle在注释里面人家说清楚了,提供了异步的支持了。
public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactoryAware {
private final Log logger = LogFactory.getLog(getClass());
// 超时时间。 单位是TimeUnit.MILLISECONDS。异步任务同步的等待时间,这是给每一个phase都起作用的
private volatile long timeoutPerShutdownPhase = 30000;
// 运行标志
private volatile boolean running;
// beanFactory
@Nullable
private volatile ConfigurableListableBeanFactory beanFactory;
// 设置超时
public void setTimeoutPerShutdownPhase(long timeoutPerShutdownPhase) {
this.timeoutPerShutdownPhase = timeoutPerShutdownPhase;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) {
if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
throw new IllegalArgumentException(
"DefaultLifecycleProcessor requires a ConfigurableListableBeanFactory: " + beanFactory);
}
this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
}
private ConfigurableListableBeanFactory getBeanFactory() {
ConfigurableListableBeanFactory beanFactory = this.beanFactory;
Assert.state(beanFactory != null, "No BeanFactory available");
return beanFactory;
}
// Lifecycle implementation
// 启动 所有已经注册到BeanFactory中的bean,这些bean实现了Lifecycle接口,
// 对于实现了SmartLifecycle的接口,将会通过阶段这个对象来控制,阶段按照从小到大的顺序来排列。
// 没有实现SmartLifecycle的接口,会采用默认值0,bean依赖其他的bean,在这个bean启动之前,先启动依赖的bean。
@Override
public void start() {
// 这里的启动是启动所有,
startBeans(false);
this.running = true;
}
// 停止所有的bean
// 也是按照阶段来分的,不过这里的顺序和上面的相反,从高到低。
// 对于依赖也是和上面是同样的操作。先停止依赖的bean。
@Override
public void stop() {
stopBeans();
this.running = false;
}
// LifecycleProcessor接口的实现,在context refresh的时候,调用,和start方法一样,不过传递的参数不一样,
@Override
public void onRefresh() {
startBeans(true); // 这里只是启动自动启动功能的bean
this.running = true;
}
@Override
public void onClose() {
stopBeans();
this.running = false;
}
@Override
public boolean isRunning() {
return this.running;
}
// autoStartupOnly表示是否只启动自动启动的类。
private void startBeans(boolean autoStartupOnly) {
// 从bean工厂中获取所有的Lifecycle的bean
Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
// key是阶段的返回值,value是LifecycleGroup。
Map<Integer, LifecycleGroup> phases = new HashMap<>();
// 开始遍历bean工厂中的lifeCycle的bean
lifecycleBeans.forEach((beanName, bean) -> {
// 如果不是自动启动,或者bean是SmartLifecycle,并且需要自动启动。
if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
int phase = getPhase(bean); // 拿到这个bean的phase。就是Phased#getPhase的返回值。
LifecycleGroup group = phases.get(phase); // 如果没有就创建,如果有,就直接添加。也就是说,LifecycleGroup是一组
// 相同phase的集合。
if (group == null) {
group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
phases.put(phase, group);
}
group.add(beanName, bean);
}
});
// 遍历,按照key的顺序,排序,调用
if (!phases.isEmpty()) {
List<Integer> keys = new ArrayList<>(phases.keySet());
Collections.sort(keys);
for (Integer key : keys) {
// 注意,这个启动是启动一组Lifecycle。
phases.get(key).start();
}
}
}
// 真正做做调用的地方。
// lifecycleBeans 就是bean工厂中所有实现了Lifecycle的集合。
// beanName要启动的bean的名字
// autoStartupOnly是否要自动启动
private void doStart(Map<String, ? extends Lifecycle> lifecycleBeans, String beanName, boolean autoStartupOnly) { // 先移除
Lifecycle bean = lifecycleBeans.remove(beanName);
if (bean != null && bean != this) {
// 依赖的bean
String[] dependenciesForBean = getBeanFactory().getDependenciesForBean(beanName);
for (String dependency : dependenciesForBean) {
// 先调用依赖的bean的start方法
doStart(lifecycleBeans, dependency, autoStartupOnly);
}
// 如果没有运行,并且 不是自动启动或者不是SmartLifecycle,或者是SmartLifecycle并且是自动启动的。
if (!bean.isRunning() &&
(!autoStartupOnly || !(bean instanceof SmartLifecycle) || ((SmartLifecycle) bean).isAutoStartup())) {
if (logger.isTraceEnabled()) {
logger.trace("Starting bean '" + beanName + "' of type [" + bean.getClass().getName() + "]");
}
try {
// 直接启动
bean.start();
}
catch (Throwable ex) {
throw new ApplicationContextException("Failed to start bean '" + beanName + "'", ex);
}
if (logger.isDebugEnabled()) {
logger.debug("Successfully started bean '" + beanName + "'");
}
}
}
}
// 停止,不过这里的phases顺序是相反的。
private void stopBeans() {
Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
Map<Integer, LifecycleGroup> phases = new HashMap<>();
lifecycleBeans.forEach((beanName, bean) -> {
int shutdownPhase = getPhase(bean);
LifecycleGroup group = phases.get(shutdownPhase);
if (group == null) {
group = new LifecycleGroup(shutdownPhase, this.timeoutPerShutdownPhase, lifecycleBeans, false);
phases.put(shutdownPhase, group);
}
group.add(beanName, bean);
});
if (!phases.isEmpty()) {
List<Integer> keys = new ArrayList<>(phases.keySet());
keys.sort(Collections.reverseOrder());
for (Integer key : keys) {
phases.get(key).stop();
}
}
}
// 真正开始stop的地方
private void doStop(Map<String, ? extends Lifecycle> lifecycleBeans, final String beanName,
final CountDownLatch latch, final Set<String> countDownBeanNames) {
Lifecycle bean = lifecycleBeans.remove(beanName);
if (bean != null) {
String[] dependentBeans = getBeanFactory().getDependentBeans(beanName);
for (String dependentBean : dependentBeans) {
// 递归调用,自己调用自己。
doStop(lifecycleBeans, dependentBean, latch, countDownBeanNames);
}
try {
// bean如果是运行的
if (bean.isRunning()) {
if (bean instanceof SmartLifecycle) {
if (logger.isTraceEnabled()) {
logger.trace("Asking bean '" + beanName + "' of type [" +
bean.getClass().getName() + "] to stop");
}
// countDownBeanNames是smart的集合
countDownBeanNames.add(beanName);
// 这是直接调用他的stop方法,并且传递了一个一段操作。
((SmartLifecycle) bean).stop(() -> {
// countdowm 利用这种方式做同步
latch.countDown();
countDownBeanNames.remove(beanName);
if (logger.isDebugEnabled()) {
logger.debug("Bean '" + beanName + "' completed its stop procedure");
}
});
}
else {
// 如果不是smartLifecycle,就直接调用他的stop方法
if (logger.isTraceEnabled()) {
logger.trace("Stopping bean '" + beanName + "' of type [" +
bean.getClass().getName() + "]");
}
bean.stop();
if (logger.isDebugEnabled()) {
logger.debug("Successfully stopped bean '" + beanName + "'");
}
}
}
else if (bean instanceof SmartLifecycle) {
// Don't wait for beans that aren't running...
latch.countDown();
}
}
catch (Throwable ex) {
if (logger.isWarnEnabled()) {
logger.warn("Failed to stop bean '" + beanName + "'", ex);
}
}
}
}
protected Map<String, Lifecycle> getLifecycleBeans() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
Map<String, Lifecycle> beans = new LinkedHashMap<>();
String[] beanNames = beanFactory.getBeanNamesForType(Lifecycle.class, false, false);
for (String beanName : beanNames) {
String beanNameToRegister = BeanFactoryUtils.transformedBeanName(beanName);
boolean isFactoryBean = beanFactory.isFactoryBean(beanNameToRegister);
String beanNameToCheck = (isFactoryBean ? BeanFactory.FACTORY_BEAN_PREFIX + beanName : beanName);
if ((beanFactory.containsSingleton(beanNameToRegister) &&
(!isFactoryBean || matchesBeanType(Lifecycle.class, beanNameToCheck, beanFactory))) ||
matchesBeanType(SmartLifecycle.class, beanNameToCheck, beanFactory)) {
Object bean = beanFactory.getBean(beanNameToCheck);
if (bean != this && bean instanceof Lifecycle) {
beans.put(beanNameToRegister, (Lifecycle) bean);
}
}
}
return beans;
}
private boolean matchesBeanType(Class<?> targetType, String beanName, BeanFactory beanFactory) {
Class<?> beanType = beanFactory.getType(beanName);
return (beanType != null && targetType.isAssignableFrom(beanType));
}
protected int getPhase(Lifecycle bean) {
return (bean instanceof Phased ? ((Phased) bean).getPhase() : 0);
}
private class LifecycleGroup {
// phase值
private final int phase;
// 等待时间
private final long timeout;
// beanfactory中Lifecycle的实现类
private final Map<String, ? extends Lifecycle> lifecycleBeans;
// 是否只启动自动启动的bean
private final boolean autoStartupOnly;
// 同一个节点的LifecycleGroupMember的集合
private final List<LifecycleGroupMember> members = new ArrayList<>();
// smartMemberCount的数量
private int smartMemberCount;
public LifecycleGroup(
int phase, long timeout, Map<String, ? extends Lifecycle> lifecycleBeans, boolean autoStartupOnly) {
this.phase = phase;
this.timeout = timeout;
this.lifecycleBeans = lifecycleBeans;
this.autoStartupOnly = autoStartupOnly;
}
// 将对象添加到members里面。用LifecycleGroupMember包装。
public void add(String name, Lifecycle bean) {
this.members.add(new LifecycleGroupMember(name, bean));
if (bean instanceof SmartLifecycle) {
// 如果是smartLifeCycle,计数++
// 这个++的目的是为了之后的创建countdownLatch,保证同步
this.smartMemberCount++;
}
}
public void start() {
if (this.members.isEmpty()) {
return;
}
if (logger.isDebugEnabled()) {
logger.debug("Starting beans in phase " + this.phase);
}
Collections.sort(this.members);
for (LifecycleGroupMember member : this.members) {
doStart(this.lifecycleBeans, member.name, this.autoStartupOnly);
}
}
public void stop() {
if (this.members.isEmpty()) {
return;
}
if (logger.isDebugEnabled()) {
logger.debug("Stopping beans in phase " + this.phase);
}
//倒叙排序
this.members.sort(Collections.reverseOrder());
CountDownLatch latch = new CountDownLatch(this.smartMemberCount);
Set<String> countDownBeanNames = Collections.synchronizedSet(new LinkedHashSet<>());
Set<String> lifecycleBeanNames = new HashSet<>(this.lifecycleBeans.keySet());
for (LifecycleGroupMember member : this.members) {
if (lifecycleBeanNames.contains(member.name)) {
doStop(this.lifecycleBeans, member.name, latch, countDownBeanNames);
}
else if (member.bean instanceof SmartLifecycle) {
// Already removed: must have been a dependent bean from another phase
latch.countDown();
}
}
try {
// 当前的这个为啥在这里等地,
latch.await(this.timeout, TimeUnit.MILLISECONDS);
if (latch.getCount() > 0 && !countDownBeanNames.isEmpty() && logger.isInfoEnabled()) {
logger.info("Failed to shut down " + countDownBeanNames.size() + " bean" +
(countDownBeanNames.size() > 1 ? "s" : "") + " with phase value " +
this.phase + " within timeout of " + this.timeout + "ms: " + countDownBeanNames);
}
}
catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
/**
* Adapts the Comparable interface onto the lifecycle phase model.
*/
private class LifecycleGroupMember implements Comparable<LifecycleGroupMember> {
private final String name;
private final Lifecycle bean;
LifecycleGroupMember(String name, Lifecycle bean) {
this.name = name;
this.bean = bean;
}
// 话说,这个比较有意思吗?都同一个组了,这个phase不都是一样的吗?
@Override
public int compareTo(LifecycleGroupMember other) {
int thisPhase = getPhase(this.bean);
int otherPhase = getPhase(other.bean);
return Integer.compare(thisPhase, otherPhase);
}
}
}
那么DefaultLifecycleProcessor在哪里调用的?还是之前的老办法?点看看调用的地方
调用
在AbstractApplicationContext里面调用,会在BeanFactory中检测bean的名字为lifecycleProcessor,如果没有就创建一个DefaultLifecycleProcessor。
initLifeCycleProcessor会在refresh方法里面调用。也就是在标准的启动流程里面,会调用。
先创建,在调用。调用LifecycleProcessor#onRefresh方法。从这里开始就会启动。走上面分析的SmartLifecycle的逻辑使用
使用
比如WebSocketConnectionManager
类
这个类主要是用来管理WebSocket
。
在start方法里面通过url来打开连接,在stop方法里面关闭
具体的可以在看看。
关于博客这件事,我是把它当做我的笔记,里面有很多的内容反映了我思考的过程,因为思维有限,不免有些内容有出入,如果有问题,欢迎指出。一同探讨。谢谢。