Lifecycle和SmartLifecycle的正确使用姿势

本文详细介绍了Spring框架中的Lifecycle和SmartLifecycle接口,对比两者功能,解释如何使用它们来控制组件的启动和停止,特别是在容器生命周期级别的操作。并通过代码示例展示了SmartLifecycle的额外功能,如自动启动和控制多个实例的执行顺序。

一、前言

  Lifecycle是Spring中最基础的生命周期接口,该接口定义了容器启动停止的方法。方便开发者扩展自己的特定逻辑,比如启动和停止某些后台进程。
  SmartLifecycle是对Lifecycle的一个扩展接口,当我们实现SmartLifecycle接口时,发现需要实现很多方法。很多同学不理解这些方法是干嘛的,今天我们来一起探讨下~

二、先说Lifecycle

  Lifecycle常用来管理一个组件的启动和停止,这个组件可以是一个线程、或者是一件事情。有同学可能会有这样的疑惑:开始和停止的逻辑写在一个bean的初始化方法和销毁方法中不可以了吗,为什么要实现个Lifecycle接口呢?这里说明一下,bean的初始化方法和销毁方法是Bean生命周期级别的;而Lifecycle是容器生命周期级别的。
我们来看下使用步骤~

1. 定义一个类并实现Lifecycle接口
public class MyLifecycle implements Lifecycle {
    /**
     * A 组件的运行状态
     */
    private volatile boolean running = false;

    /**
     * 容器启动后调用
     */
    @Override
    public void start() {
        System.out.println("lifecycle 容器启动完成,启动A组件...");
        running = true;
    }

    /**
     * 容器停止时调用
     */
    @Override
    public void stop() {
        System.out.println("lifecycle 收到关闭容器的信号,关闭A组件...");
        running = false;
    }

    /**
     * 检查此组件是否正在运行。
     * 1. 只有该方法返回false时,start方法才会被执行。
     * 2. 只有该方法返回true时,stop(Runnable callback)或stop()方法才会被执行。
     */
    @Override
    public boolean isRunning() {
        System.out.println("lifecycle 检查A组件的运行状态:" + running);
        return running;
    }
}

Spring每次调用start()stop()方法之前,都会调用下isRunning()方法。来检测下这个A组件,是否已经启动或停止过了。如果通过isRunning()方法,检测到A组件已经是运行状态了,就无需再调用start()方法启动A组件。

2. 把MyLifecycle交给Spring管理
<bean id="myLifecycle" class="com.kaka.spring.pojo.custom.MyLifecycle"/>

以上配置在lifecycle.xml文件中

3. 执行
    @Test
    public void lifecycleTest() {
        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext(
                "lifecycle.xml");
        // 必须显示调用
        classPathXmlApplicationContext.start();
        classPathXmlApplicationContext.stop();
    }

运行结果
在这里插入图片描述
这里强调一下,一定要显示调用容器的start()和stop()方法,Lifecycle的接口方法才会被执行。但是一般项目中(比如ssm和springboot),都不会显示调用容器的start()方法,所以就有了SmartLifecycle接口的出现。

三、再谈SmartLifecycle

SmartLifecycle是Lifecycle的一个子接口,比Lifecycle有更丰富的功能。其中有两点最重要的改进:

  1. 无需容器显示调用start()方法,就可以回调SmartLifecycle接口的start()
  2. 容器中如果有多个SmartLifecycle实例,可以方便控制调用顺序。

用法和Lifecycle一样,我们来看下

1. 定义一个类实现SmartLifecycle接口
public class MySmartLifecycle implements SmartLifecycle {
    private volatile boolean running = false;

    /**
     * 如果该`Lifecycle`类所在的上下文在调用`refresh`时,希望能够自己自动进行回调,则返回`true`* ,
     * false的值表明组件打算通过显式的start()调用来启动,类似于普通的Lifecycle实现。
     */
    @Override
    public boolean isAutoStartup() {
        return true;
    }

    /**
     * 很多框架中的源码中,都会把真正逻辑写在stop()方法内。
     * 比如quartz和Redis的spring支持包
     *
     * @param callback
     */
    @Override
    public void stop(Runnable callback) {
        System.out.println("smartLifecycle stop runnable 容器停止...");
        stop();
        callback.run();
    }

    @Override
    public void start() {
        System.out.println("smartLifecycle 容器启动完成 ...");
        running = true;
    }

    @Override
    public void stop() {
        System.out.println("smartLifecycle stop 容器停止 ...");
        running = false;
    }

    @Override
    public boolean isRunning() {
        System.out.println("smartLifecycle 检查运行状态 ...");
        return running;
    }

    /**
     * 阶段值   越小越靠前执行start()方法,越靠后执行stop()方法
     *
     * @return
     */
    @Override
    public int getPhase() {
        return 0;
    }
}

一共需要实现6个方法,确实要不少啊,不是start()和stop()就行了吗?好吧,我们一个个解释下~

方法名描述
isAutoStartup()这个一定要返回true,不然就跟Lifecycle一样了。
getPhase()控制多个SmartLifecycle的回调顺序的,返回值越小越靠前执行start()方法,越靠后执行stop()方法
isRunning()与Lifecycle接口中的功能一样,用来判你的断组件是否在运行。
start()与Lifecycle接口中的功能一样,当刷新容器(也就是启动完成)时调用。
stop(Runnable callback)当容器停止时,回调该方法。当执行完你自定义的逻辑后,一定要调用下callback.run(); 这个是为了,告诉容器你已停止自己的组件完成。
这里多说一点,很多源码会在该方法内仅写两行代码,参考上面例子。一行是stop();把真正的逻辑转发到stop()这个方法。另一行就是必须调用的callback.run();
stop()不会被Spring框架调用到!
2. 把MySmartLifecycle交给Spring管理
<bean id="mySmartLifecycle" class="com.kaka.spring.pojo.custom.MySmartLifecycle"/>

以上配置在lifecycle.xml文件中

3. 执行
    @Test
    public void lifecycleTest() {
        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext(
                "lifecycle.xml");
        // 模拟框架中的停止方法
        classPathXmlApplicationContext.stop();
    }

执行结果在这里插入图片描述

四、总结

  • 需要根据Spring容器的生命周期,来做一些自己的逻辑时,一般都会选择自定义一个类,实现SmartLifecycle这个接口。很少有人会使用Lifecycle
  • 容器中有多个SmartLifecycle时,可以使用接口中的getPhase()方法控制回调的顺序。方法返回值越小,越靠前执行start()方法,越靠后执行stop()方法
  • SmartLifecycle这个接口的isAutoStartup()方法,一定要返回true,容器启动时才会回调SmartLifecycle的start()方法。
  • stop(Runnable callback)方法是有超时时间的,默认为30s。可以通过以下方式设置超时时间
<bean id="lifecycleProcessor" class="org.springframework.context.support.DefaultLifecycleProcessor">
    <!-- timeout value in milliseconds -->
    <property name="timeoutPerShutdownPhase" value="10000"/>
</bean>
内容概要:本文档围绕“光伏并网逆变器序阻抗建模、扫频辨识与弱电网交互稳定性分析”展开,提供基于MatlabSimulink的完整代码与仿真模型,复现了相关博士论文的核心研究成果。内容聚焦于新能源发电系统接入弱电网时的稳定性问题,系统阐述了光伏逆变器的正负序阻抗建模方法、小信号扫频辨识技术、锁相环与电流环的动态耦合效应、LCL滤波器的作用机制以及系统宽频带振荡的失稳机理。通过构建精确的序阻抗模型并结合扫频法进行稳定性判据分析,深入揭示并网逆变器与弱电网间的交互特性,为实际工程中振荡问题的预测、诊断与抑制提供坚实的理论支撑与有效的技术路径。; 适合人群:具备电力电子、自动控制理论及新能源发电系统基础知识,正在从事相关领域研究的硕士/博士研究生、高校科研人员以及电力系统行业的工程师。; 使用场景及目标:①复现并验证博士论文中关于光伏逆变器序阻抗建模与弱电网交互稳定性的关键结论;②作为科研项目或学位论文的技术蓝本,开展弱电网环境下并网系统稳定性仿真与机理研究;③深入掌握Matlab/Simulink在电力系统小信号稳定性分析、特别是阻抗建模与扫频法应用方面的高级仿真技能。; 阅读建议:学习者应结合所提供的Matlab代码与Simulink仿真模型,亲手运行并调试扫频辨识程序,细致分析序阻抗建模的每一步推导与实现过程,重点关注锁相环动态特性对系统稳定裕度的影响,通过调整控制器参数与电网强度观察系统响应变化,从而深刻理解交互失稳的内在机理,实现从理论到实践的融会贯通。
内容概要:本文介绍了如何利用有限元分析获得的磁通链接图来建立永磁同步电机(PMSM)的高精度数学模型,并在Simulink环境中实现仿真。该方法通过精确捕捉电机内部复杂的磁场分布,克服传统建模中因理想化假设导致的精度不足问题,从而显著提升模型的真实性与可靠性。文中系统阐述了从有限元仿真数据提取、磁链特性曲线拟合到导入Simulink构建动态仿真模型的完整流程,重点强调了数据处理的关键步骤与模型参数的映射关系,为高性能电机控制算法的设计、验证与优化提供了高保真的仿真平台。; 适合人群:具备电机学、电磁场理论基础及Simulink/MATLAB仿真能力的高校研究生、科研院所研究人员以及从事电机控制与电力电子系统开发的工程技术专家。; 使用场景及目标:①用于高校科研机构开展先进PMSM控制策略(如FOC、MPC)的研究与教学实验;②服务于工业界对高精度电机数字孪生模型的需求,支持新型电机驱动系统的快速原型开发与性能测试;③帮助研究人员深入探究PMSM的非线性特性(如饱、交叉耦合)及其对系统动态性能的影响。; 阅读建议:建议读者结合具体的电机设计参数与应用场景,严格按照文中所述的数据处理与建模流程进行实践操作,特别注意有限元软件与Simulink之间的数据接口规范与单位一致性,确保物理信息的无损转换。同时,可进一步通过实验数据对仿真模型进行校准与验证,以评估其在不同工况下的准确性与鲁棒性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值