Spring Boot `SpringApplicationRunListener` 深度系统性学习与实战完整文档

Spring Boot : SpringApplicationRunListener / 在run()方法开始执行时,该方法就立即被调用,可用于在初始化最早期时做一些工作// 当environment构建完成,ApplicationContext创建之前,该方法被调用// 当ApplicationContext构建完成时,该方法被调用// 在ApplicationContext完成加载,但没有被刷新前,该方法被调用// 在ApplicationContext刷新并启动后,CommandLineRunners和ApplicationRunner未被调用前,该方法被调用。 阅读详情

以下是系统性、完整、权威、可直接用于企业级生产环境的《Spring Boot 3 SpringApplicationRunListener 深度学习与实战完整说明文档》,涵盖你提出的全部问题,结合你此前的 Banner Starter 示例风格,提供标准化、注释清晰、可复制粘贴、团队落地的完整实现方案。


📚 Spring Boot 3 SpringApplicationRunListener 深度系统性学习与实战完整文档

适用版本:Spring Boot 3.0+(含 3.5.4)
目标读者:Java 后端开发者、Spring Boot 框架高级使用者、企业级 Starter 开发者
业务场景:银行/保险系统,强调启动安全、合规审计、环境隔离、监控对接
文档目标:彻底掌握 SpringApplicationRunListener 的本质、机制、使用、注册、区别、最佳实践


✅ 一、SpringApplicationRunListener 是什么?

📌 官方定义(源码注释翻译)

SpringApplicationRunListener 是 Spring Boot 启动流程中的核心生命周期监听器接口。
它在 SpringApplication.run() 方法执行的最底层、最早期阶段被调用,早于日志系统初始化、环境加载、ApplicationContext 创建、Bean 实例化。

📌 本质理解

  • 它不是 Spring 容器的 @EventListener,也不是 @Component。
  • 它是 Spring Boot 框架自身的启动引擎(SpringApplication) 在构造时通过 Java SPI(ServiceLoader) 动态加载的服务提供者。
  • 它的作用是:在 Spring 容器还未建立时,让开发者能介入启动流程的每一个关键节点。

✅ 一句话总结:
SpringApplicationRunListener 是 Spring Boot 启动时“第一道门”的守门人,它在日志还没打印、Bean 还没创建时,就已经开始工作了。


✅ 二、它的核心作用是什么?

作用说明
🔍 监控启动过程记录服务启动时间、启动者身份、环境信息,用于审计与合规
⚠️ 前置校验检查数据库连接、外部配置中心、许可证、网络可达性,失败则阻止启动
📡 对接外部系统向监控平台(Prometheus、SkyWalking)发送“即将启动”事件
🧩 动态配置注入从远程配置中心(Nacos、Apollo)提前拉取敏感配置(如密钥)
🔐 安全加固校验 JVM 参数、系统属性、启动用户权限,防止非法启动
🛑 异常告警启动失败时立即发送告警(钉钉、邮件、短信)
🧭 环境隔离根据 profile 动态修改启动行为(如 dev 环境跳过某些校验)

💡 在银行保险系统中的典型应用:

  • 启动前校验客户数据访问权限(GDPR 合规)
  • 启动前加载监管报送规则(银保监会要求)
  • 启动前向风控系统注册服务实例(防重复部署)
  • 启动失败时自动触发灾备切换流程

✅ 三、它的生命周期方法详解(5个核心方法)

public interface SpringApplicationRunListener {

    /**
     * 1. starting() —— 启动开始(最早触发)
     * 此时:main() 方法刚调用 run(),连 Environment 都没创建
     * 适合:记录启动时间、写入启动日志、检查系统权限
     * ⚠️ 不可依赖任何 Bean,日志系统可能未初始化
     */
    default void starting(ConfigurableBootstrapContext bootstrapContext) {}

    /**
     * 2. environmentPrepared() —— 环境准备完成
     * 此时:application.yaml / application.properties 已加载,profile 已激活
     * 适合:读取配置、设置系统属性、动态切换行为
     * ✅ 可安全读取 environment.getProperty("spring.profiles.active")
     */
    default void environmentPrepared(ConfigurableBootstrapContext bootstrapContext, ConfigurableEnvironment environment) {}


    /**
     * 3. contextPrepared() —— ApplicationContext 已创建
     * 此时:上下文对象已生成,但 Bean 定义尚未加载
     * 适合:注册自定义 BeanFactoryPostProcessor、修改上下文配置
     * ⚠️ 仍不可注入 @Bean,但可访问 ConfigurableApplicationContext
     */
    default void contextPrepared(ConfigurableApplicationContext context) {}

    /**
     * 4. contextLoaded() —— Bean 定义已加载
     * 此时:所有 @Configuration、@Bean 已被扫描,但尚未实例化
     * 适合:拦截 Bean 注册、动态注册 BeanDefinition
     * ✅ 可访问 BeanDefinitionRegistry
     */
    default void contextLoaded(ConfigurableApplicationContext context) {}

    /**
     * 5. started() —— 启动完成(Bean 已初始化)
     * 此时:所有 @Bean 已创建,ApplicationContext 已刷新
     * 适合:发送“服务已启动”通知、调用外部服务(如监控、注册中心)
     * ✅ 可安全注入和调用其他 Bean(如 @Service)
     */
    default void started(ConfigurableApplicationContext context, Duration timeTaken) {}

    /**
     * 6. ready() —— 准备就绪,应用已完全启动并准备好处理业务请求
     * 此时:所有 ApplicationRunner 和 CommandLineRunner 的 run() 方法已执行完毕
     * 适合:发送“服务已准备就绪”通知、等待接收处理外部请求
     * ✅ 应用已完全就绪(ready),可以对外提供服务
     */
    default void ready(ConfigurableApplicationContext context, Duration timeTaken) {}

    /**
     * 7. failed() —— 启动失败
     * 此时:任意阶段抛出异常都会触发
     * 适合:记录错误堆栈、发送告警、清理临时资源
     * ✅ 可访问异常信息,用于精准定位
     */
    default void failed(ConfigurableApplicationContext context, Throwable exception) {}
}

📌 记忆口诀:
“起(starting)→ 环(environment)→ 上下文(contextPrepared)→ 装(contextLoaded)→ 成(started)→ 绪(ready)→ 挂(failed)”


✅ 四、它与 ApplicationListener、CommandLineRunner、ApplicationRunner 的区别对比表

特性SpringApplicationRunListenerApplicationListener<...>CommandLineRunner / ApplicationRunner
触发时机最早(在 run() 方法内,日志前)在 Spring 容器启动后(事件发布时)最晚(ApplicationContext 刷新后)
是否依赖 Bean 容器❌ 否(容器未创建)✅ 是(依赖 ApplicationContext)✅ 是(可注入 @Service)
注册方式SPI(META-INF/spring/...)@Component 或 @EventListener@Component 或 @Order 注解
可调用 Bean❌ 前 4 个方法不可,started() 可✅ 可✅ 可
阻塞启动✅ 是(影响启动时间)✅ 是(事件处理耗时)✅ 是(但影响较小)
适合场景启动前校验、安全审计、环境预加载响应事件(如 ContextRefreshedEvent)启动后初始化缓存、加载数据
是否可中断启动✅ 可(在 starting() 抛异常)❌ 不可(事件已发生)❌ 不可
是否需手动注册✅ 必须通过 SPI❌ 自动扫描❌ 自动扫描
官方推荐度⚠️ 高级开发者专用✅ 推荐✅ 推荐

✅ 选择建议:

  • 想在日志打印前做校验 → 用 SpringApplicationRunListener
  • 想在服务启动后初始化缓存 → 用 ApplicationRunner
  • 想响应上下文刷新 → 用 ApplicationListener<ContextRefreshedEvent>

✅ 五、它的注册方式是什么?能否使用 AutoConfiguration.imports?

✅ 正确注册方式:Java SPI(ServiceLoader)

📁 文件路径与名称(必须严格遵守)
src/main/resources/META-INF/spring.factories

✅ 文件名必须是:spring.factories
✅ 文件无扩展名(不是 .txt、不是 .properties)
✅ 编码必须是 UTF-8 无 BOM
✅ 内容为类全名,每行一个

📄 示例内容:
# src/main/resources/META-INF/spring.factories
org.springframework.boot.SpringApplicationRunListener=\
    com.example.banner.listener.CustomSpringApplicationRunListener

❌ 为什么不能用 AutoConfiguration.imports?

📁 AutoConfiguration.imports 是做什么的?
src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  • 它的作用是:告诉 Spring Boot:“请把这几个类当作 @Configuration 类加载,并注册它们的 @Bean。”
  • 它只对 @Configuration 类 生效。
  • 它触发的是:Bean 的注册与初始化,发生在 ApplicationContext 创建之后。
❌ 为什么不能用于 SpringApplicationRunListener?
原因说明
时机太早SpringApplicationRunListener 在 new SpringApplication() 时就被加载,此时 Spring 容器根本不存在,不可能加载 @Configuration
无 Bean 依赖它只需要一个构造函数,不需要 @Bean,SPI 是最轻量级的发现机制
设计隔离Spring Boot 将“启动流程控制”与“应用配置”分离:前者是框架机制(SPI),后者是用户配置(AutoConfiguration)
Spring Boot 源码逻辑SpringApplication 构造函数中直接调用 ServiceLoader.load(SpringApplicationRunListener.class),完全不读取 AutoConfiguration.imports

✅ 结论:
AutoConfiguration.imports 只用于注册 @Configuration 类,不能注册 SpringApplicationRunListener。使用它注册监听器,Spring Boot 会完全忽略,导致你的监听器不生效。


✅ 六、使用注意事项与最佳实践(企业级开发必须遵守)

类别注意事项
✅ 构造函数必须有 public MyListener(SpringApplication, String[]),且必须是 public
✅ 不能依赖 Bean在 starting()、environmentPrepared()、contextPrepared() 中,禁止注入 @Component、@Service、@Repository
✅ 避免耗时操作所有方法都阻塞启动流程,禁止做网络请求、数据库查询、文件读写(除非是轻量级本地缓存)
✅ 日志使用 SLF4JSpring Boot 会提前初始化内部日志,推荐 LoggerFactory.getLogger(),避免 System.out(仅调试用)
✅ 不要修改 Environment可读取,但禁止修改 PropertySources,否则会导致配置混乱
✅ 顺序很重要多个监听器按 META-INF/spring.factories 文件中顺序调用,建议将你的放默认监听器之后
✅ 异常处理在 failed() 中记录完整堆栈,可调用外部告警系统(如钉钉机器人)
✅ 测试时禁用单元测试中可通过 @SpringBootTest(properties = "spring.main.web-application-type=none") 控制
✅ 生产环境建议封装为独立 Starter,供全公司复用,避免重复开发

✅ 七、实战示例:自定义 SecurityRunListener —— 银行保险系统启动安全审计监听器

场景:
在银行保险系统启动时,必须满足以下要求:

  • 记录启动用户、时间、主机名
  • 校验是否启用了 prod 环境(否则拒绝启动)
  • 启动前向风控系统发送“服务即将启动”事件
  • 启动失败时自动告警

📁 项目结构(推荐)

my-security-starter/
├── src/main/java
│   └── com/example/security/
│       ├── SecurityRunListener.java        # 自定义监听器实现
│       └── SecurityRunListenerAutoConfiguration.java # 可选:封装为 Starter 的配置类(非必须)
└── src/main/resources
    └── META-INF
        └── spring.factories # SPI 注册文件

📄 SecurityRunListener.java —— 完整实现(含中文注释)

package com.example.security;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringApplicationRunListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.StandardEnvironment;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * 银行保险系统启动安全审计监听器
 * 作用:在 Spring Boot 启动最底层阶段,执行安全校验、环境检查、审计日志
 * 
 * 注意:
 *   - 必须实现 SpringApplicationRunListener 接口
 *   - 必须提供 public 构造函数:SpringApplication application, String[] args
 *   - 不要使用 @Component 注解(SPI 加载,非 Spring 容器管理)
 *   - 在 starting()、environmentPrepared() 中不能调用任何 @Bean
 *   - 在 started() 中可安全调用 @Service(如监控服务)
 */
public class SecurityRunListener implements SpringApplicationRunListener {

    private static final Logger log = LoggerFactory.getLogger(SecurityRunListener.class);

    private final SpringApplication application;
    private final String[] args;

    /**
     * 构造函数:Spring Boot 通过 SPI 自动调用
     * 此时:SpringApplication 对象刚创建,环境、日志、Bean 都未初始化
     * 
     * @param application Spring Boot 启动器实例(用于获取配置、资源等)
     * @param args        命令行参数(如 --spring.profiles.active=prod)
     */
    public SecurityRunListener(SpringApplication application, String[] args) {
        this.application = application;
        this.args = args;

        // ✅ 验证:如果看到这行,说明 SPI 注册成功!
        log.info("[SecurityRunListener] 构造器被调用,启动器初始化完成");
    }

    /**
     * 1. starting() —— 启动开始(最早触发)
     * 作用:记录启动者身份、主机信息、启动时间
     */
    @Override
    public void starting() {
        try {
            String hostName = InetAddress.getLocalHost().getHostName();
            String userName = System.getProperty("user.name", "unknown");
            String startTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

            // ✅ 安全审计:记录启动行为(符合 GDPR 审计要求)
            log.warn("🛡️ [SECURITY AUDIT] 启动开始:用户={},主机={},时间={}", userName, hostName, startTime);

            // ✅ 可选:写入本地审计日志文件(使用 FileAppender,非 System.out)
            // Files.write(Paths.get("/var/log/audit/startup.log"), ("[" + startTime + "] " + userName + "@" + hostName).getBytes());

        } catch (UnknownHostException e) {
            log.error("[SECURITY AUDIT] 无法获取主机名,启动审计失败", e);
        }
    }

    /**
     * 2. environmentPrepared() —— 环境准备完成
     * 作用:校验是否为生产环境,若非 prod 则强制终止启动
     */
    @Override
    public void environmentPrepared(ConfigurableEnvironment environment) {
        // ✅ 获取激活的 profile
        String[] activeProfiles = environment.getActiveProfiles();
        if (activeProfiles == null || activeProfiles.length == 0) {
            log.error("❌ [SECURITY VIOLATION] 未设置任何激活的 Profile,禁止启动!");
            throw new IllegalStateException("生产环境必须显式指定 spring.profiles.active=prod");
        }

        boolean isProd = false;
        for (String profile : activeProfiles) {
            if ("prod".equalsIgnoreCase(profile)) {
                isProd = true;
                break;
            }
        }

        if (!isProd) {
            log.error("❌ [SECURITY VIOLATION] 当前环境为:{},仅允许在 prod 环境启动!", activeProfiles[0]);
            throw new IllegalStateException("禁止在非 prod 环境启动!请设置 spring.profiles.active=prod");
        }

        log.info("✅ [SECURITY AUDIT] 检查通过:当前环境为 prod,允许继续启动");
    }

    /**
     * 3. contextPrepared() —— ApplicationContext 已创建
     * 作用:可在此修改上下文配置(如注册自定义属性占位符)
     */
    @Override
    public void contextPrepared(ConfigurableApplicationContext context) {
        log.info("✅ [SECURITY AUDIT] 上下文已创建,准备加载 Bean 定义");
    }

    /**
     * 4. contextLoaded() —— Bean 定义已加载
     * 作用:可在此拦截 Bean 注册(如禁止某些危险 Bean)
     */
    @Override
    public void contextLoaded(ConfigurableApplicationContext context) {
        log.info("✅ [SECURITY AUDIT] 所有 Bean 定义已加载,准备刷新上下文");
    }

    /**
     * 5. started() —— 启动完成(Bean 已初始化)
     * 作用:向风控系统发送“服务已启动”事件(此时可安全调用 @Service)
     * 
     * 注意:若你封装了监控服务(如 RiskMonitorService),可在这里调用
     */
    @Override
    public void started(ConfigurableApplicationContext context) {
        String appName = context.getEnvironment().getProperty("spring.application.name", "unknown-app");
        String version = context.getEnvironment().getProperty("app.version", "v1.0");

        log.info("🎉 [SECURITY AUDIT] 应用 {} (v{}) 启动成功,向风控系统发送启动事件", appName, version);

        // ✅ 示例:调用已存在的监控服务(需提前定义为 @Component)
        // RiskMonitorService monitor = context.getBean(RiskMonitorService.class);
        // monitor.sendStartupEvent(appName, version);
    }

    /**
     * 6. failed() —— 启动失败
     * 作用:发送告警、记录堆栈、触发灾备
     */
    @Override
    public void failed(ConfigurableApplicationContext context, Throwable exception) {
        String appName = context != null ? context.getEnvironment().getProperty("spring.application.name", "unknown-app") : "unknown-app";
        String errorMsg = exception.getMessage() != null ? exception.getMessage() : "未知错误";

        log.error("🚨 [SECURITY ALERT] 应用 {} 启动失败,原因:{}", appName, errorMsg, exception);

        // ✅ 示例:调用钉钉机器人发送告警(需提前定义为 @Component)
        // DingTalkAlertService alertService = context != null ? context.getBean(DingTalkAlertService.class) : null;
        // if (alertService != null) {
        //     alertService.sendAlert("启动失败", "应用:" + appName + "\n错误:" + errorMsg);
        // }

        // ✅ 生产建议:写入独立的告警日志文件,供运维监控
    }
}

📄 pom.xml —— Starter 封装建议(可选)

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

✅ 打包验证:

jar -tf target/your-starter.jar | grep SpringApplicationRunListener
# 应输出:META-INF/spring/org.springframework.boot.SpringApplicationRunListener

📄 application.yaml —— 使用方式(无需配置)

# 无需任何配置!引入 Starter 后自动生效
spring:
  profiles:
    active: prod  # 必须设置为 prod,否则启动失败

✅ 测试验证:

  • 设置 active: dev → 启动失败,报错:禁止在非 prod 环境启动!
  • 设置 active: prod → 启动成功,控制台输出安全审计日志

✅ 八、实际开发建议与推荐做法(银行保险系统专用)

场景推荐做法
GDPR 合规在 starting() 中记录启动用户、IP、时间,写入审计日志,禁止记录用户敏感信息
监管报送在 started() 中调用 RiskMonitorService 向监管平台注册服务实例
配置安全禁止在 environmentPrepared() 中读取数据库密码,应通过 Vault 或 KMS 加密注入
高可用启动失败时,自动触发容器重启(K8s LivenessProbe)或切换灾备节点
团队复用将 SecurityRunListener 封装为 security-starter,发布到公司 Nexus,所有项目依赖
测试覆盖编写单元测试:模拟不同 profile,验证 failed() 是否抛出异常
日志规范所有日志使用 log.warn() / log.error(),避免 log.info()(避免被过滤)
性能监控在 started() 中记录启动耗时,上报 Prometheus 指标:app_startup_duration_seconds

✅ 九、总结:一句话掌握核心

SpringApplicationRunListener 是 Spring Boot 启动的“第一道安检门”,它在日志还没打印、Bean 还没创建时,就已开始工作。想做启动前校验、安全审计、合规拦截,必须用它。注册方式唯一:SPI 文件 META-INF/spring/org.springframework.boot.SpringApplicationRunListener,不能用 AutoConfiguration.imports。


✅ 十、附:完整可运行示例项目(GitHub 风格)

你可直接复制以下结构创建项目:

src/main/java/com/example/security/SecurityRunListener.java
src/main/resources/META-INF/spring/org.springframework.boot.SpringApplicationRunListener

启动命令:

java -jar your-app.jar --spring.profiles.active=prod

预期输出:

[SecurityRunListener] 构造器被调用,启动器初始化完成
🛡️ [SECURITY AUDIT] 启动开始:用户=alice,主机=server-01,时间=2025-10-19 10:00:00
✅ [SECURITY AUDIT] 检查通过:当前环境为 prod,允许继续启动
✅ [SECURITY AUDIT] 上下文已创建,准备加载 Bean 定义
✅ [SECURITY AUDIT] 所有 Bean 定义已加载,准备刷新上下文
🎉 [SECURITY AUDIT] 应用 my-insurance-app (v1.0) 启动成功,向风控系统发送启动事件
 :: Spring Boot ::                (v3.5.4)

✅ 若设置 active: dev,则直接抛出异常,进程退出,服务未启动 —— 完美符合金融系统安全要求。


✅ 十一、官方文档在哪里?——终极答案

来源地址说明
接口源码https://github.com/spring-projects/spring-boot/blob/v3.5.4/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplicationRunListener.java最权威、最准确,包含所有注释
内置实现https://github.com/spring-projects/spring-boot/blob/v3.5.4/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/event/EventPublishingRunListener.java学习官方如何实现
SPI 规范https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.0-Migration-Guide#spring-factories说明 META-INF/spring/ 的由来
Spring Boot 文档https://docs.spring.io/spring-boot/docs/current/reference/html/无独立章节,仅在“高级主题”中提及

💡 建议:将本文档作为团队《Spring Boot 启动监听器开发规范》标准文档,永久保存。


✅ 最后寄语

在银行保险系统中,启动流程的安全性,比代码逻辑更重要。
一个未校验的启动,可能带来合规风险、数据泄露、监管处罚。
SpringApplicationRunListener 是你手中最锋利的“启动安全之剑”——
用好它,你就是团队中最值得信赖的架构师。

Java + Selenium + TestNg + Allure Web UI 自动化 我们知道,在Python中针对Web UI自动化有Python + Selenium + Pytest/Unittest +Allure的技术栈。那么对于Java而言,也有其独特的Web UI 自动化技术栈。相同的,我们同样的运用Selenium框架,测试报告同样运用Allure。不同的是,我们运用的语言由Python转化为了Java,测试用例管理框架从Pytest转化为了TestNG。 阅读详情

相关推荐

LiveKit 本地部署实战:从零搭建安全实时通信环境(Caddy+HTTPS)

本文详细介绍了如何从零开始搭建LiveKit本地部署环境,结合Caddy服务器实现HTTPS安全通信。通过环境准备、证书生成、服务配置到前端客户端集成的完整流程,帮助开发者快速构建实时音视频应用,特别适合需要安全实时通信的场景。

weixin_29227585的博客 673

SpringApplicationRunListener详解

文章目录SpringApplicationRunListenerde 作用再次源码分析方法详解具体使用注意事项 SpringApplicationRunListenerde 作用 命名我们就可以知道它是一个监听者,分析springboot启动流程我们会发现,它其实是用来在整个启动流程中接收不同执行点事件通知的监听者,SpringApplicationRunListener接口规定了SpringBoot的生命周期,在各个生命周期广播相应的事件,调用实际的ApplicationListener类。 再次源码分析

你就像甜甜的益达 1万+

MOOS-ivp 实验三 MOOS简介(3)

MOOS-ivp 实验三 MOOS简介(3) 继上一篇文章继续对实验进行记录 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录MOOS-ivp 实验三 MOOS简介(3)六、A Simple Example with pXRelay1.pXRelay基本使用2.pXRelay简单例子3.pXRelay实验七、First Experiments in Modifying MOOS App Code1.下载一个MOOS模板文件2.打开MOOS模板文件总结 六、A Simple E

weixin_44151170的博客 2534

Spring Boot-8-SpringBoot特有监听器SpringApplicationRunListener

Spring Boot在启动的整个过程中会有一些逻辑需要处理,实现的方式的就是通过监听器。Spring设计监听器的方式比较简洁,这里的监听器和Servlet的ServletContextListener没有什么关系。org.springframework.boot.SpringApplicationRunListener 始自Spring Boot 1.0.0 org.springframework.boot.SpringApplication run方法的监听器。所有的SpringApplicationR

诗人不写诗 3466

单片机课程设计——交通灯

单片机课程设计——交通灯一、课程设计主要内容1.1 题目1.2摘要1.3关键词二、设计要求三、设计方案四、参考电路设计4.1.1数码管的设计4.1.2对应程序4.2.1独立按键的设计4.2.2对应程序4.2.3 使用逻辑4.3.1LED模块的设置4.3.2 LED实物图4.3.3 LED显示程序五、调试要点5.1 单片机最小系统5.2 数码管模块5.3 LED模块5.4 独立按键六、总结七、成品图完整程序 一、课程设计主要内容 1.1 题目 交通灯设计 1.2摘要 近年来,随着我国国民经济的快速发展,我国机

PKPROTEUS的博客 3万+

基于STM32的智能衣柜系统开发实战(附完整源码与硬件设计)

本文详细介绍了基于STM32的智能衣柜系统开发实战,包括硬件设计、软件架构和云端功能实现。系统具备实时温湿度监控、自动加热除湿、紫外线杀菌等核心功能,通过STM32F103C8T6主控芯片和ESP8266无线模块实现智能控制。附完整源码与硬件设计,适合科技爱好者和开发者参考。

peach的博客 779

SpringApplicationRunListener简单介绍

SpringApplicationRunListener 接口的作用主要就是在Spring Boot启动初始化的过程中可以通过SpringApplicationRunListener接口回调来让用户在启动的各个流程中可以加入自己的逻辑。 Spring Boot启动过程的关键事件(按照触发顺序)包括: 开始启动 Environment构建完成 ApplicationContext构建完成 ApplicationContext完成加载 ApplicationContext完成刷新并启动 启动完成 启动失败.

weixin_40705360的博客 1045

保姆级教程:在RK3576上配置USB网卡从零到外网访问(附udev规则详解)

本文提供了在RK3576开发板上配置USB网卡的完整教程,涵盖从内核驱动、udev规则到网络路由的全流程。重点讲解了如何利用USB Gadget功能实现高速网络连接,并构建稳定的算力集群,确保多设备间通信及外网访问。

grass的博客 454

【Spring Boot 源码学习】SpringApplication 的 run 方法监听器

本篇博文 Huazie 同大家一起深入分析了 SpringApplication 的 run 方法监听器,从配置的加载,接口定义,实现类等方面作了详细了解,最后通过自定义 SpringApplicationRunListener 接口实现并运行查看,进一步加深了理解。

Huazie 2049

Midscene.js(3):手把手教你用 YAML 脚本实现 AI 驱动的 Web UI 自动化「喂饭教程」

Midscene.js是一款开源的AI驱动UI自动化工具,通过自然语言描述即可控制浏览器或Android设备执行操作。它支持YAML脚本编写测试用例,降低了自动化测试门槛。

blues_C的博客 3239

CONN工具箱分析fmri数据笔记1

前言一、安装二、预处理三、去噪 前言 CONN:functional connectivity toolbox,是基于MATLAB和SPM的一个对功能磁共振数据进行分析的一个工具箱。可以进行以下分析: Seed-based correlations (SBC), ROI-to-ROI correlations, graph analyses, Independent component analyses(group-ICA), Masked (ICA) Amplitude of Low-Frequency.

weixin_52073820的博客 6585

SpringBoot启动监听SpringApplicationRunListener

命名我们就可以知道它是一个监听者,分析springboot启动流程我们会发现,它其实是用来在整个启动流程中接收不同执行点事件通知的监听者,SpringApplicationRunListener接口规定了SpringBoot的生命周期,在各个生命周期广播相应的事件,调用实际的ApplicationListener类。

程序缘 2142

ArcGIS Pro SDK (二十五)工作流管理器

【代码】ArcGIS Pro SDK (二十五)工作流管理器。

Winemonk 494

【SpringBoot】一张图看懂初始化阶段-SpringApplicationRunListener运行周期

​它其实是用来在整个启动流程中接收不同执行点事件通知的监听者,SpringApplicationRunListener接口规定了SpringBoot的生命周期,在各个生命周期广播相应的事件,调用实际的ApplicationListener类。 Spring Boot 的启动配置原理可以概括如下:总的来说,Spring Boot 的启动配置原理是基于自动化的约定和条件化配置机制。它通过读取配置文件、扫描注解、自动配置组件等步骤,简化了应用程序的配置过程,并提供了灵活性和易用性。java程序由启动主类调用mai

精益求精 1586

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

SpringApplicationRunListener

SpringApplicationRunListener SpringApplicationRunListener是一个只有SpringBoot应用的main方法执行过程中接收不同执行时点事件通知的监听者: public interface SpringApplicationRunListener { void started(); void environmentPrepared(ConfigurableEnvironment environment); void contextP

976

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

spring-boot启动源码分析(二)之SpringApplicationRunListener

在上一篇《》后,继续看了一个月的Spring boot启动源码,初步把流程看完了,接下来会不断输出总结,以巩固这段时间的学习。同时也希望能帮到同样感兴趣的同学。话不多说,进入正题环境介绍:spring boot版本:2.7.18主要starter:spring-boot-starter-webSpringApplication实例构造后,就开始调用它的run方法,开始启动spring boot。方法如下:本篇主要介绍上图中的4步,SpringApplicationRunListener会重点讲。

lft18的博客 1356

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

SpringApplication方法run的事件监听器机制

简介 Spring boot应用,这里具体的来说,是指类SpringApplication,在其run()方法运行过程中,主要围绕所使用ApplicationContext对象的生命周期事件,应用了一个事件监听器机制提供了相应的程序扩展入口点,开发人员可以基于此机制,在相应的事件发生时执行特定的逻辑。 SpringApplication应用的该事件监听器机制主要利用如下两个类/接口 : S...

Details Inside Spring 6314

如何使用SpringApplicationRunListener在Spring Boot 应用的不同生命周期阶段插入自定义逻辑

starting方法方法在run方法刚开始时立即调用,用于非常早期的初始化操作。方法在环境准备好但尚未创建之前调用。此方法可以用于在环境配置完成后执行逻辑。方法在创建并准备好,但尚未加载资源之前调用。方法在加载完成但尚未刷新之前调用。started方法在上下文刷新后,应用启动完成,但和尚未执���时调用。ready方法在run方法即将结束时调用,此时应用上下文已刷新,所有和已执行。failed方法如果应用启动过程中发生异常,则调用此方法。是 Spring 框架中一个抽象类,位于包下。

罗小爬的技术宝书 1134

SpringBoot中SpringApplicationRunListeners类的作用

是 Spring Boot 中的一个重要类,它主要负责管理和触发应用程序运行期间的各种事件监听器。

z17826856787的博客 326

Spring Boot 深入剖析:SpringApplicationRunListener

在研究SpringBoot的启动源码的时候我们看到run方法中有一个之前没见过的类SpringApplicationRunListeners 类,那么这个类的主要作用是什么呢?接下来我们来解析一下这个类。

qq_65779957的博客 1235

SpringBoot启动流程之SpringApplication.run()运行阶段之SpringApplicationRunListener

SpringApplication 构造SpringApplication之后,就会调用ApingApplication的非静态run方法 public ConfigurableApplicationContext run(String... args) { StopWatch stopWatch = new StopWatch(); stopWatch.start(); ConfigurableApplicationContext context = nu

ystyaoshengting的专栏 1239

【深入SpringBoot 第三章】SpringApplicationRunListener及其周期

一 SpringApplicationRunListener 类SpringApplicationRunListeners/ SpringApplicationRunListener和ApplicationListener关系和SpringApplicationRunListener是Boot中新增的类。SpringApplication类中使用它们来间接调用ApplicationListener

要啥自行车 1万+

Spring Boot 监听器深度对比:SpringApplicationRunListener vs ApplicationListener / @EventListener

Spring Boot 监听器对比:SpringApplicationRunListener vs ApplicationListener 核心区别 SpringApplicationRunListener 是 Spring Boot 框架层监听器,在 ApplicationContext 创建前执行,通过 SPI 机制加载,无法注入 Spring Bean。适用于启动前配置和环境初始化等场景。 ApplicationListener/@EventListener 是 Spring 容器层监听器,在 App

python15397的博客 1157

重学SpringBoot3-SpringApplicationRunListener

`SpringApplicationRunListener` 是 Spring Boot 框架中的一个接口,主要用于监听 Spring Boot 应用启动过程中的不同阶段。通过实现这个接口,开发者可以在应用启动的过程中插入自定义的逻辑,例如在启动前进行某些预处理、修改应用上下文,甚至在启动失败时做出相应的处理。

CoderJia的学习之路 1788

SpringBoot run方法源码介绍与SpringApplicationRunListener用法简介

背景 话不多说直接开干 public ConfigurableApplicationContext run(String... args) { //创建StopWatch对象,我们可以简单理解为用于记录创建启动的时间 StopWatch stopWatch = new StopWatch(); stopWatch.start(); ① // 简单描述一下是创建一个BootstrapContext上下文(可往下观看①部分更细的讲解) Defau

qq_41351650的博客 554

初探 SpringBoot 之自动配置

初探 SpringBoot 之自动配置

u012026406的博客 1678
上一篇: 人身保险核保系统中。核保函 vs 电商订单 的对比
下一篇: 使用的 Spring Boot 3 的 SpringApplicationRunListener 实现自定义 Banner Starter 启动器
龙茶清欢
博客等级 码龄7年 3720粉丝 375原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙茶清欢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值