千家信息网

Spring中SmartLifecycle的用法是怎样的

发表于:2024-09-22 作者:千家信息网编辑
千家信息网最后更新 2024年09月22日,这期内容当中小编将会给大家带来有关Spring中SmartLifecycle的用法是怎样的,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获!Spring SmartLi
千家信息网最后更新 2024年09月22日Spring中SmartLifecycle的用法是怎样的

这期内容当中小编将会给大家带来有关Spring中SmartLifecycle的用法是怎样的,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获!

Spring SmartLifecycle用法

Spring SmartLifecycle 在容器所有bean加载和初始化完毕执行

在使用Spring开发时,我们都知道,所有bean都交给Spring容器来统一管理,其中包括每一个bean的加载和初始化。

有时候我们需要在Spring加载和初始化所有bean后,接着执行一些任务或者启动需要的异步服务,这样我们可以使用 SmartLifecycle 来做到。

SmartLifecycle 是一个接口

当Spring容器加载所有bean并完成初始化之后,会接着回调实现该接口的类中对应的方法(start()方法)。

import org.springframework.context.SmartLifecycle;import org.springframework.stereotype.Component;/** * SmartLifecycle测试 * *  *  */@Componentpublic class TestSmartLifecycle implements SmartLifecycle {    private boolean isRunning = false;    /**     * 1. 我们主要在该方法中启动任务或者其他异步服务,比如开启MQ接收消息
* 2. 当上下文被刷新(所有对象已被实例化和初始化之后)时,将调用该方法,默认生命周期处理器将检查每个SmartLifecycle对象的isAutoStartup()方法返回的布尔值。 * 如果为"true",则该方法会被调用,而不是等待显式调用自己的start()方法。 */ @Override public void start() { System.out.println("start"); // 执行完其他业务后,可以修改 isRunning = true isRunning = true; } /** * 如果工程中有多个实现接口SmartLifecycle的类,则这些类的start的执行顺序按getPhase方法返回值从小到大执行。
* 例如:1比2先执行,-1比0先执行。 stop方法的执行顺序则相反,getPhase返回值较大类的stop方法先被调用,小的后被调用。 */ @Override public int getPhase() { // 默认为0 return 0; } /** * 根据该方法的返回值决定是否执行start方法。
* 返回true时start方法会被自动执行,返回false则不会。 */ @Override public boolean isAutoStartup() { // 默认为false return true; } /** * 1. 只有该方法返回false时,start方法才会被执行。
* 2. 只有该方法返回true时,stop(Runnable callback)或stop()方法才会被执行。 */ @Override public boolean isRunning() { // 默认返回false return isRunning; } /** * SmartLifecycle子类的才有的方法,当isRunning方法返回true时,该方法才会被调用。 */ @Override public void stop(Runnable callback) { System.out.println("stop(Runnable)"); // 如果你让isRunning返回true,需要执行stop这个方法,那么就不要忘记调用callback.run()。 // 否则在你程序退出时,Spring的DefaultLifecycleProcessor会认为你这个TestSmartLifecycle没有stop完成,程序会一直卡着结束不了,等待一定时间(默认超时时间30秒)后才会自动结束。 // PS:如果你想修改这个默认超时时间,可以按下面思路做,当然下面代码是springmvc配置文件形式的参考,在SpringBoot中自然不是配置xml来完成,这里只是提供一种思路。 // // // // callback.run(); isRunning = false; } /** * 接口Lifecycle的子类的方法,只有非SmartLifecycle的子类才会执行该方法。
* 1. 该方法只对直接实现接口Lifecycle的类才起作用,对实现SmartLifecycle接口的类无效。
* 2. 方法stop()和方法stop(Runnable callback)的区别只在于,后者是SmartLifecycle子类的专属。 */ @Override public void stop() { System.out.println("stop"); isRunning = false; }}

SmartLifecycle 解读

org.springframework.context.SmartLifecycle解读

1、接口定义

/** * An extension of the {@link Lifecycle} interface for those objects that require to * be started upon ApplicationContext refresh and/or shutdown in a particular order. * The {@link #isAutoStartup()} return value indicates whether this object should * be started at the time of a context refresh. The callback-accepting * {@link #stop(Runnable)} method is useful for objects that have an asynchronous * shutdown process. Any implementation of this interface must invoke the * callback's run() method upon shutdown completion to avoid unnecessary delays * in the overall ApplicationContext shutdown. * * 

This interface extends {@link Phased}, and the {@link #getPhase()} method's * return value indicates the phase within which this Lifecycle component should * be started and stopped. The startup process begins with the lowest * phase value and ends with the highest phase value (Integer.MIN_VALUE * is the lowest possible, and Integer.MAX_VALUE is the highest possible). The * shutdown process will apply the reverse order. Any components with the * same value will be arbitrarily ordered within the same phase. * *

Example: if component B depends on component A having already started, then * component A should have a lower phase value than component B. During the * shutdown process, component B would be stopped before component A. * *

Any explicit "depends-on" relationship will take precedence over * the phase order such that the dependent bean always starts after its * dependency and always stops before its dependency. * *

Any Lifecycle components within the context that do not also implement * SmartLifecycle will be treated as if they have a phase value of 0. That * way a SmartLifecycle implementation may start before those Lifecycle * components if it has a negative phase value, or it may start after * those components if it has a positive phase value. * *

Note that, due to the auto-startup support in SmartLifecycle, * a SmartLifecycle bean instance will get initialized on startup of the * application context in any case. As a consequence, the bean definition * lazy-init flag has very limited actual effect on SmartLifecycle beans. * * @author Mark Fisher * @since 3.0 * @see LifecycleProcessor * @see ConfigurableApplicationContext */public interface SmartLifecycle extends Lifecycle, Phased { /** * Returns {@code true} if this {@code Lifecycle} component should get * started automatically by the container at the time that the containing * {@link ApplicationContext} gets refreshed. *

A value of {@code false} indicates that the component is intended to * be started through an explicit {@link #start()} call instead, analogous * to a plain {@link Lifecycle} implementation. * @see #start() * @see #getPhase() * @see LifecycleProcessor#onRefresh() * @see ConfigurableApplicationContext#refresh() */ boolean isAutoStartup(); /** * Indicates that a Lifecycle component must stop if it is currently running. *

The provided callback is used by the {@link LifecycleProcessor} to support * an ordered, and potentially concurrent, shutdown of all components having a * common shutdown order value. The callback must be executed after * the {@code SmartLifecycle} component does indeed stop. *

The {@link LifecycleProcessor} will call only this variant of the * {@code stop} method; i.e. {@link Lifecycle#stop()} will not be called for * {@code SmartLifecycle} implementations unless explicitly delegated to within * the implementation of this method. * @see #stop() * @see #getPhase() */ void stop(Runnable callback); }

从注释文档里可以看出:

1、是接口 Lifecycle 的拓展,且会在应用上下文类ApplicationContext 执行 refresh and/or shutdown 时会调用

2、方法 isAutoStartup() 返回的值会决定,当前实体对象是否会被调用,当应用上下文类ApplicationContext 执行 refresh

3、stop(Runnable) 方法用于调用Lifecycle的stop方法

4、getPhase() 返回值用于设置LifeCycle的执行优先度:值越小优先度越高

5、isRunning() 决定了start()方法的是否调用

2、应用

public class SmartLifecycleImpl implements SmartLifecycle {    private Boolean isRunning = false;    @Override    public boolean isAutoStartup() {        return true;    }     @Override    public void stop(Runnable callback) {        callback.run();    }     @Override    public void start() {        System.out.println("SmartLifecycleImpl is starting ....");        isRunning = true;    }     @Override    public void stop() {        System.out.println("SmartLifecycleImpl is stopped.");    }    /**     * 执行start()方法前会用它来判断是否执行,返回为true时,start()方法不执行     */    @Override    public boolean isRunning() {        return isRunning;    }     @Override    public int getPhase() {        return 0;    }}

启动类

public class ProviderBootstrap {     public static void main(String[] args) throws Exception {        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ProviderConfiguration.class);        context.start();        System.in.read();    }     @Configuration    static class ProviderConfiguration {         @Bean        public SmartLifecycleImpl getSmartLifecycleImpl(){            return new SmartLifecycleImpl();        }    }}

可以发现,类SmartLifecycleImpl提交给spring容器后,启动后,会输出 start() 方法的方法体。

上述就是小编为大家分享的Spring中SmartLifecycle的用法是怎样的了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注行业资讯频道。

方法 接口 子类 容器 上下 上下文 只有 对象 时间 应用 任务 内容 思路 程序 顺序 分析 服务 配置 较大 从小到大 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 河北节能软件开发服务价钱 湖北交友软件开发定做 分布式数据库查询处理的查询时间如何计算 中国计算机服务器是哪个公司研发 曲靖互联网科技可以吗 饥荒本地服务器什么意思 csgo跳跃服务器 杭州直播软件开发平台 济南定制化国产服务器什么价格 杭州欣悦互联网科技有限公司 数据库实验报告sql 非法获取 普通数据库 碧空之歌服务器热度 网络安全纳入保密 重庆网络安全技术服务 大众点评服务器出现故障 适合学数学的软件开发 迁移服务器最安全有效的方法 青少年网络安全公开课美篇 数据库中笛卡儿积怎么解释 广州视觉传感器软件开发 网络安全购物注意事项 邮政银行软件开发中心二面 哈尔滨租房软件开发 网络技术知识答题竞赛 软件开发 创业 一对多数据库设计 我的世界服务器管理员的规则 新起点上开创网络安全工作 web3d用什么服务器好用
0