0%

Spring Boot Runner 详解:ApplicationRunner 与 CommandLineRunner 实战指南

在 Spring Boot 应用中,若需在 SpringApplication.run() 启动完成后自动执行初始化逻辑(如加载配置、初始化缓存、校验依赖服务),可通过 ApplicationRunnerCommandLineRunner 接口实现。这两个接口均为 Spring Boot 提供的 “启动后回调” 扩展点,核心作用是在 Spring 上下文初始化完成后、应用对外提供服务前执行自定义逻辑。从 “接口差异→实现方式→执行顺序→实战场景” 四个维度,系统讲解 Runner 的使用方法与底层原理。

Runner 接口核心作用与差异

ApplicationRunnerCommandLineRunner 功能高度相似,均用于 “启动后执行逻辑”,但在参数接收方式上存在关键差异,适用于不同场景。

1. 接口定义对比

(1)ApplicationRunner 接口
1
2
3
4
5
6
7
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;

public interface ApplicationRunner {
// 参数为 ApplicationArguments 对象,支持解析命令行参数(含选项参数和非选项参数)
void run(ApplicationArguments args) throws Exception;
}
(2)CommandLineRunner 接口
1
2
3
4
5
6
import org.springframework.boot.CommandLineRunner;

public interface CommandLineRunner {
// 参数为 String 数组,直接接收原始命令行参数(不解析,按输入顺序存储)
void run(String... args) throws Exception;
}

2. 核心差异:参数处理方式

阅读全文 »

SSL 协议:网络通信的安全基石

SSL(Secure Sockets Layer,安全套接字协议)是一种位于 TCP/IP 协议栈中传输层与应用层之间的安全协议,其核心作用是通过加密、认证和完整性校验,为上层应用(如 HTTP、SMTP、FTP)提供安全的通信通道,防止数据在传输过程中被窃听、篡改或伪造。尽管 SSL 已被 TLS(Transport Layer Security)取代,但其设计理念和核心机制仍是现代网络安全的基础。

SSL 协议的核心目标

SSL 协议通过三层防护机制,实现网络通信的 “机密性、真实性、完整性”:

  1. 机密性:通过加密算法对传输数据进行加密,确保只有通信双方能解密读取。
  2. 真实性:通过数字证书验证通信双方的身份(尤其是服务器身份),防止中间人冒充。
  3. 完整性:通过消息认证码(MAC)检测数据是否在传输中被篡改。

SSL 协议的分层结构

SSL 协议采用分层设计,分为记录协议握手协议两大部分,每层专注于不同的安全功能:

1. SSL 记录协议(Record Protocol)

  • 作用:位于最底层,负责对上层协议(如握手协议、应用数据)的数据进行分段、压缩、加密和校验,是所有 SSL 数据传输的基础。
  • 工作流程:
    1. 接收上层数据(如握手消息、HTTP 请求),将其分割为最大 2^14 字节的块。
    2. 可选压缩(现代 SSL/TLS 中较少使用,避免压缩侧信道攻击)。
    3. 计算消息认证码(MAC),用于完整性校验。
    4. 使用对称加密算法(如 AES)对数据和 MAC 进行加密。
    5. 添加 SSL 记录首部(包含版本、长度等信息),通过 TCP 发送。
  • 核心算法:对称加密(AES、3DES)、哈希算法(SHA-256,用于 MAC 计算)。

2. SSL 握手协议(Handshake Protocol)

  • 作用:位于记录协议之上,是 SSL 协议中最复杂的部分,负责在通信前完成算法协商、密钥交换和身份认证,为后续加密通信奠定基础。
  • 握手流程(简化版):
    1. 客户端问候(Client Hello):客户端向服务器发送支持的 SSL 版本、加密套件(如TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384)、随机数(Client Random)。
    2. 服务器问候(Server Hello):服务器回应选择的 SSL 版本、加密套件、随机数(Server Random),并发送服务器数字证书。
    3. 客户端验证服务器:客户端验证服务器证书的有效性(检查颁发机构、有效期、是否被吊销),确认服务器身份。
    4. 密钥交换:
      • 若使用非对称加密(如 RSA):客户端生成 “预主密钥(Pre-Master Secret)”,用服务器公钥加密后发送给服务器。
      • 若使用密钥协商算法(如 ECDHE):双方交换公钥参数,各自计算出相同的预主密钥(更安全,支持前向 secrecy)。
    5. 生成会话密钥:客户端和服务器分别用 Client Random、Server Random 和 Pre-Master Secret,通过相同算法生成主密钥(Master Secret),再派生出用于加密和 MAC 的会话密钥。
    6. 握手完成:双方发送 “完成消息”(用会话密钥加密),确认握手成功,后续通信使用会话密钥加密。
阅读全文 »

浏览器内核详解

浏览器内核(Rendering Engine)是浏览器的核心组件,负责解析网页内容(HTML、CSS、JavaScript 等)并将其渲染为可视化页面。不同浏览器采用不同的内核,这也是导致网页在不同浏览器中可能呈现差异的主要原因之一。

主流浏览器及其内核

目前主流浏览器所使用的内核如下:

  • Microsoft Edge(新版):自 2019 年起,新版 Edge 放弃了原有的 EdgeHTML 内核,转而采用Blink 内核(基于 Chromium 项目),与 Chrome 保持一致。
  • Google Chrome、Opera:使用Blink 内核(Blink 是 WebKit 的分支,由 Google 主导开发)。
  • Mozilla Firefox:使用Gecko 内核,这是 Firefox 一直以来坚持使用的自主研发内核。
  • Apple Safari:使用WebKit 内核,该内核在苹果生态(如 macOS、iOS)中广泛应用。

浏览器内核发展时间线及演变

浏览器内核的发展经历了多个阶段,诞生顺序及演变关系如下:

阅读全文 »

线程死锁:原理、成因与解决方案

线程死锁是多线程编程中常见的隐性问题,指两个或多个线程相互等待对方持有的资源,导致所有线程陷入无限期阻塞的状态。死锁一旦发生,程序往往无法自动恢复,需通过代码设计规避或手动干预解决。

死锁的核心成因

死锁的产生必须同时满足以下四个必要条件,缺一不可:

  1. 互斥条件
    资源具有排他性,同一时间只能被一个线程占用(如synchronized锁、文件句柄等)。
  2. 请求与保持条件
    线程持有部分资源,同时又请求其他线程已持有的资源,且不释放自身已占有的资源。
  3. 不剥夺条件
    线程已获得的资源,在未主动释放前,不能被其他线程强行剥夺(如 Java 的内置锁无法被强制释放)。
  4. 循环等待条件
    多个线程形成环形等待链,每个线程都在等待下一个线程持有的资源(如线程 A 等线程 B 的资源,线程 B 等线程 A 的资源)。

死锁示例代码

以下是一个典型的死锁场景:两个线程分别持有对方需要的锁,且都不释放自身的锁。

阅读全文 »