Spring Boot 中内置Tomcat如何加载项目?Current ClassLoader的概念浅析

本文详细介绍了Spring Boot内置Tomcat如何加载项目,包括不打包直接运行和打包成jar的情况。重点解析了Spring Boot自定义的LaunchedURLClassLoader以及current ClassLoader的概念,强调了理解这两个概念对于理解类加载机制的重要性,特别是对于热部署和远程加载等场景的应用。

在java web开发中,相较于传统的Spring,Spring Boot带来的一大好处是其内置的Servlet容器。在这个特性的帮助下,使得开发无需额外配置外部的Servlet容器,只需要一个Application类即可启动一个内置容器,这在微服务的开发,部署中尤为重要,带来了更多地便利性。

Apache Tomcat 作为大多数公司使用的Servlet容器,同时也是Spring Boot的默认内置容器。
在传统的外置Tomcat的情况下,我们通常把我们需要部署的项目放在/webapp目录下,这样Tomcat就可以检测到我们的项目进行加载部署。但是在Spring Boot中,这一步又是如何完成的呢?

tomcat类加载器

对Tomcat稍有理解的开发人员应该知道,Tomcat内部实现了自己的类加载器,用来打破双亲委派机制。

在这里插入图片描述

上图就是一个Tomcat启动后的类加载器图。
其中最顶层的BootStrapClassLoader,ExtClassLoader,AppClassLoader是java自身的类加载器。而其后的加载器则全部是Tomcat自己实现的类加载器。
这里不花费太多的篇幅来论述这些加载器的原理,源码讲解,只简单的说一下。

可以看到上图中,commomLoader,catalinaLoader,sharedLoader的首字母没有大写,这是由于他们实际上并不是一个新类,他们的实现都是JDK中的URLClassLoader,他们只是作为Tomcat中的一个类的属性存在,分别负责加载不同路径的Class。但是在Tomcat 6.x后,Tomcat的开发者们把这3个不同的路径合并成了一个一个文件夹,既lib 文件夹。基于此,在默认的情况下,这3个loader实际上是指向同一个引用。
WebAppClassLoader加载的就是我们实际的应用的Class文件,它可以有多个。
更底层的JasperLoader对应的是JSP编译后的Class文件,每一个JSP对应一个JasperLoader。

在这个架构中,WebAppClassLoader的上层都是遵循双亲委派机制的,他们的实现是为了加载一些Tomcat自身需要的Class,或者所有webApp都需要的Class。WebAppClassLoader这个加载器重写了方法,打破了双亲委派机制。到达这个类加载器时,它会首先判断能否使用自身加载,只有在无法使用自身去加载的时候才会把这个任务抛向更上层。至于JasperLoader的出现是为了实现JSP的热加载,每个JSP对应一个JasperLoader,当检测到一个JSP进行了修改,Tomcat就会把这个JSP对应的JasperLoader的抛弃,重新新建一个JasperLoader加载这个JSP,以此来实现热加载。

Spring Boot 的内置Tomcat如何加载我们的项目

这里需要区分两种情况,打成jar包时如何加载?不打包直接运行Application时如何加载?

<think>嗯,用户的问题非常聚焦:HotSeconds是否支持非Spring Boot项目的本地热部署。这需要结合插件原理和引用信息综合分析。 从引用[2][3]可以明确两个关键点:第一,HotSeconds的核心能力是通过字节码替换实现热更新,这种机制与框架无关;第二,它的设计目标就是通用Java应用场景。尤其引用[2]提到“也可以本地热部署”时并未限定框架,引用[3]强调“吊打市面插件”也暗示其广泛适用性。 不过用户可能需要更落地的验证。我想到几个技术支撑点:首先,插件通过附加到JVM的javaagent实现重载,这是JVM标准特性;其次,其客户端插件只依赖项目引入的hotseconds-core.jar,框架无关;最后,引用[1]对比表格显示它比spring-boot-devtools更通用。 考虑到用户可能是传统JavaEE开发者,需要特别说明Servlet容器的支持情况。根据开源文档,Tomcat/Jetty等主流容器只要启动参数配置了-javaagent就能工作。配置文件路径这细节也要提醒,比如WEB-INF/classes的资源路径差异。 应该强调“加载隔离”这个潜在坑点。非SpringBoot项目往往有复杂的加载层次,比如OSGi或自定义ClassLoader,这时需要参考HotSeconds文档配置白名单。另外静态变量问题在非Spring场景同样存在,需要同步说明。 </think>是的,**HotSeconds 完全支持非 Spring Boot 项目的本地热部署**,其热更新机制不依赖特定框架。以下是关键说明: --- ### **核心原理与支持范围** 1. **字节码替换技术** HotSeconds 通过 Java Agent 和字节码操作实现热更新,核心是 **JVM 的重定义(`Instrumentation.redefineClasses()`)** [^2][^3]。该技术是 **JVM 原生能力**,与 Spring Boot 等框架无关。 2. **通用 Java 项目支持** 只要项目能在标准 JVM 上运行(如普通 Java 应用、Servlet 容器项目等),均可使用 HotSeconds 热部署: - **本地部署**:通过 IDEA 插件直接加载修改后的 `.class` 文件[^2][^3]。 - **配置要求**:仅需在 `JVM 启动参数` 中添加 `-javaagent:hotseconds-agent.jar`(本地开发时插件通常自动处理)[^3]。 --- ### **非 Spring Boot 项目操作步骤** 1. **添加依赖** 在项目中引入 HotSeconds 核心库(以 Maven 为例): ```xml <dependency> <groupId>io.github.hotseconds</groupId> <artifactId>hotseconds-core</artifactId> <version>最新版本</version> </dependency> ``` 2. **配置启动参数**(如需手动) 在运行配置中添加 JVM 参数: ``` -javaagent:path/to/hotseconds-agent.jar ``` 3. **使用 IDEA 插件热更新** 修改代码后点击插件 **Hot Deploy** 按钮,流程与 Spring Boot 项目一致[^2][^3]。 --- ### **注意事项** | 项目型 | 支持情况 | 说明 | |----------------|-------------------------|----------------------------------------------------------------------| | **Servlet 项目** | ✅ 支持(Tomcat/Jetty) | 需确保 Agent 加载到容器的 JVM 中[^3] | | **普通 Java 应用** | ✅ 支持 | 通过 `main` 方法启动即可 | | **资源文件** | ✅ 支持 | 需确保文件路径在加载路径中(如 `src/main/resources`)[^3] | | **结构性变更** | ⚠️ 部分支持 | 新增方法/字段需重启(JVM 限制),方法修改可热更新[^2][^3] | > 💡 **示例场景**:一个基于纯 Servlet 的 Web 项目,在 Tomcat 中启动后,修改 `doGet()` 方法逻辑 → 点击 HotSeconds 插件按钮 → 立即生效无需重启容器。 --- ### **与框架绑定工具的区别** | 工具 | 框架依赖 | 非 Spring Boot 支持 | |-----------------------|-------------------|---------------------| | **spring-boot-devtools** | 强依赖 Spring Boot | ❌ 不支持 | | **HotSeconds** | 无依赖 | ✅ 完全支持 | HotSeconds 作为 **JVM 层解决方案**,其热更新能力建立在 Java 字节码操作上,而非框架特性[^1][^3],因此各 Java 项目均可使用。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值