手写 Spring Boot 嵌入式Tomcat方案构建教学

手写 Spring Boot 嵌入式Tomcat项目开发教学

项目概述

本文将详细介绍如何从零开始开发一个基于Spring Boot和嵌入式Tomcat的Web应用程序。

该项目采用现代化的Java技术栈,展示了Spring Boot的核心特性和最佳实践。

技术栈

  • JDK: 25
  • Spring Boot: 3.x (Spring Framework 6.2.12)
  • 嵌入式Tomcat: 11.0.14
  • 模板引擎: Thymeleaf 3.1.2
  • 构建工具: Maven 3.9.9

开发思路

1. 架构设计思路

本项目采用经典的MVC架构模式,通过Spring Boot的自动配置特性简化开发流程。

选择嵌入式Tomcat作为Web容器,避免了传统部署的复杂性,使应用程序能够以独立JAR包的形式运行。

开发过程中遵循以下设计原则:

  • 约定优于配置:利用Spring Boot的默认配置减少样板代码
  • 分层架构:清晰的Controller层处理HTTP请求
  • 配置外部化:通过Java配置类替代XML配置
  • 模板分离:使用Thymeleaf实现视图与逻辑分离

2. 项目结构设计

tomcat-spring/
├── src/main/java/com/lihaozhe/     # Java源码目录
│   ├── Application.java            # 应用程序启动类
│   ├── config/                     # 配置类目录
│   │   ├── SpringConfig.java       # Spring核心配置
│   │   ├── ThymeleafConfig.java    # 模板引擎配置
│   │   └── TomcatConfig.java       # 嵌入式Tomcat配置
│   └── controller/                 # 控制器目录
│       └── HelloController.java    # 请求处理控制器
├── src/main/resources/             # 资源文件目录
│   └── templates/                  # 模板文件目录
│       └── index.html              # 首页模板
└── pom.xml                         # Maven构建配置

开发流程

第一步:项目初始化

首先创建Maven项目,配置基本的构建信息和依赖管理。

在pom.xml中定义项目的基本属性和核心依赖。

Maven配置文件 (pom.xml)
<?xml version="1.0" encoding="UTF-8"?>
  <!--
  开发思路:使用Maven构建Spring Boot项目,配置JDK 25和Spring Boot 3.x依赖
  开发过程:
  1. 设置项目基本信息和编码格式
  2. 配置JDK 25编译环境
  3. 添加Spring Boot核心依赖
  4. 配置嵌入式Tomcat
  5. 集成Thymeleaf模板引擎
  6. 配置构建插件支持可执行JAR
  -->
    <project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <!-- Maven模型版本 -->
  <modelVersion>4.0.0</modelVersion>
    <!-- 项目基本信息 -->
    <groupId>com.lihaozhe</groupId>              <!-- 组织标识 -->
    <artifactId>tomcat-spring</artifactId>      <!-- 项目标识 -->
    <version>1.0.0</version>                    <!-- 版本号 -->
    <packaging>jar</packaging>                  <!-- 打包方式 -->
      <!-- 项目属性配置 -->
        <properties>
          <!-- 项目构建编码 -->
          <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <!-- Maven编译器版本 -->
            <maven.compiler.source>25</maven.compiler.source>
            <maven.compiler.target>25</maven.compiler.target>
              <!-- 项目构建JDK版本 -->
              <maven.compiler.release>25</maven.compiler.release>
              </properties>
              <!-- 依赖管理 -->
                <dependencies>
                  <!-- Spring Web MVC核心依赖 -->
                    <dependency>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-webmvc</artifactId>
                    <version>6.2.12</version>
                    </dependency>
                    <!-- 嵌入式Tomcat核心依赖 -->
                      <dependency>
                      <groupId>org.apache.tomcat.embed</groupId>
                      <artifactId>tomcat-embed-core</artifactId>
                      <version>11.0.14</version>
                      </dependency>
                      <!-- Thymeleaf模板引擎核心依赖 -->
                        <dependency>
                        <groupId>org.thymeleaf</groupId>
                        <artifactId>thymeleaf</artifactId>
                        <version>3.1.2.RELEASE</version>
                        </dependency>
                        <!-- Thymeleaf与Spring集成依赖 -->
                          <dependency>
                          <groupId>org.thymeleaf</groupId>
                          <artifactId>thymeleaf-spring6</artifactId>
                          <version>3.1.2.RELEASE</version>
                          </dependency>
                          <!-- JSON处理依赖 -->
                            <dependency>
                            <groupId>com.fasterxml.jackson.core</groupId>
                            <artifactId>jackson-databind</artifactId>
                            <version>2.19.2</version>
                            </dependency>
                            <!-- 日志依赖 -->
                              <dependency>
                              <groupId>org.slf4j</groupId>
                              <artifactId>slf4j-api</artifactId>
                              <version>2.0.7</version>
                              </dependency>
                              <!-- 单元测试依赖 -->
                                <dependency>
                                <groupId>org.junit.jupiter</groupId>
                                <artifactId>junit-jupiter-api</artifactId>
                                <version>5.11.4</version>
                                <scope>test</scope>
                                </dependency>
                                <dependency>
                                <groupId>org.junit.jupiter</groupId>
                                <artifactId>junit-jupiter-engine</artifactId>
                                <version>5.11.4</version>
                                <scope>test</scope>
                                </dependency>
                              </dependencies>
                              <!-- 构建配置 -->
                                <build>
                                  <!-- 最终生成的jar包名称 -->
                                  <finalName>${project.name}-${version}</finalName>
                                    <!-- Maven插件配置 -->
                                      <plugins>
                                        <!-- 1. Maven编译插件:指定JDK版本,解决编译兼容性问题 -->
                                          <plugin>
                                          <groupId>org.apache.maven.plugins</groupId>
                                          <artifactId>maven-compiler-plugin</artifactId>
                                          <version>3.14.1</version>
                                            <configuration>
                                              <!-- 源代码兼容的JDK版本 -->
                                              <source>${maven.compiler.source}</source>
                                                <!-- 目标字节码兼容的JDK版本 -->
                                                <target>${maven.compiler.target}</target>
                                                  <!-- 源文件编码格式 -->
                                                  <encoding>${project.build.sourceEncoding}</encoding>
                                                    <!-- 指定JDK编译器路径(如果本地环境变量未配置) -->
                                                    <executable>D:/dev/java/jdk/jdk25/bin/javac.exe</executable>
                                                    </configuration>
                                                  </plugin>
                                                  <!-- 2. JAR打包插件:配置可执行JAR文件,支持java -jar启动 -->
                                                    <plugin>
                                                    <groupId>org.apache.maven.plugins</groupId>
                                                    <artifactId>maven-jar-plugin</artifactId>
                                                    <version>3.5.0</version>
                                                      <configuration>
                                                        <archive>
                                                          <!-- 配置MANIFEST.MF文件 -->
                                                            <manifest>
                                                              <!-- 指定main方法入口类(必须正确配置) -->
                                                              <mainClass>com.lihaozhe.Application</mainClass>
                                                                <!-- 自动添加依赖到类路径(避免ClassNotFoundException) -->
                                                                <addClasspath>true</addClasspath>
                                                                  <!-- 依赖库路径前缀 -->
                                                                  <classpathPrefix>lib/</classpathPrefix>
                                                                  </manifest>
                                                                </archive>
                                                                <!-- 排除不必要的文件 -->
                                                                  <excludes>
                                                                  <exclude>**/logback.xml</exclude>
                                                                  <exclude>**/application*.properties</exclude>
                                                                  </excludes>
                                                                </configuration>
                                                              </plugin>
                                                              <!-- 3. 资源文件处理插件:确保templates目录、配置文件正确复制到classpath -->
                                                                <plugin>
                                                                <groupId>org.apache.maven.plugins</groupId>
                                                                <artifactId>maven-resources-plugin</artifactId>
                                                                <version>3.3.1</version>
                                                                  <configuration>
                                                                    <!-- 资源文件编码格式 -->
                                                                    <encoding>${project.build.sourceEncoding}</encoding>
                                                                      <!-- 资源文件包含配置 -->
                                                                        <resources>
                                                                          <!-- 主资源目录配置 -->
                                                                            <resource>
                                                                            <directory>src/main/resources</directory>
                                                                            <filtering>true</filtering>
                                                                              <!-- 包含resources目录下所有文件 -->
                                                                                <includes>
                                                                                <include>**/*</include>
                                                                                </includes>
                                                                              </resource>
                                                                              <!-- Java目录下的XML文件配置(如MyBatis映射文件) -->
                                                                                <resource>
                                                                                <directory>src/main/java</directory>
                                                                                <filtering>false</filtering>
                                                                                  <includes>
                                                                                  <include>**/*.xml</include>
                                                                                  </includes>
                                                                                </resource>
                                                                              </resources>
                                                                            </configuration>
                                                                            <!-- 自定义资源复制阶段 -->
                                                                              <executions>
                                                                                <execution>
                                                                                <id>copy-resources</id>
                                                                                <phase>process-resources</phase>
                                                                                  <goals>
                                                                                  <goal>copy-resources</goal>
                                                                                  </goals>
                                                                                  <configuration>
                                                                                    <!-- 输出目录 -->
                                                                                    <outputDirectory>${project.build.outputDirectory}</outputDirectory>
                                                                                      <resources>
                                                                                        <resource>
                                                                                        <directory>src/main/resources</directory>
                                                                                        <filtering>true</filtering>
                                                                                          <includes>
                                                                                          <include>**/*</include>
                                                                                          </includes>
                                                                                        </resource>
                                                                                      </resources>
                                                                                    </configuration>
                                                                                  </execution>
                                                                                </executions>
                                                                              </plugin>
                                                                              <!-- 4. 依赖复制插件:将项目依赖复制到target/lib目录,方便分发 -->
                                                                                <plugin>
                                                                                <groupId>org.apache.maven.plugins</groupId>
                                                                                <artifactId>maven-dependency-plugin</artifactId>
                                                                                <version>3.9.0</version>
                                                                                  <executions>
                                                                                    <execution>
                                                                                    <id>copy-dependencies</id>
                                                                                    <phase>package</phase>
                                                                                      <goals>
                                                                                      <goal>copy-dependencies</goal>
                                                                                      </goals>
                                                                                      <configuration>
                                                                                        <!-- 依赖复制到target/lib目录 -->
                                                                                        <outputDirectory>${project.build.directory}/lib</outputDirectory>
                                                                                          <!-- 排除provided范围的依赖(避免重复) -->
                                                                                          <excludeScope>provided</excludeScope>
                                                                                          </configuration>
                                                                                        </execution>
                                                                                      </executions>
                                                                                    </plugin>
                                                                                  </plugins>
                                                                                  <!-- 资源目录配置(确保Maven识别templates等目录) -->
                                                                                    <resources>
                                                                                      <!-- 主资源目录 -->
                                                                                        <resource>
                                                                                        <directory>src/main/resources</directory>
                                                                                        <filtering>true</filtering>
                                                                                          <includes>
                                                                                          <include>**/*</include>
                                                                                          </includes>
                                                                                        </resource>
                                                                                        <!-- Java源码目录中的XML文件 -->
                                                                                          <resource>
                                                                                          <directory>src/main/java</directory>
                                                                                          <filtering>false</filtering>
                                                                                            <includes>
                                                                                            <include>**/*.xml</include> <!-- 如果有MyBatis等XML配置文件 -->
                                                                                            </includes>
                                                                                          </resource>
                                                                                        </resources>
                                                                                      </build>
                                                                                    </project>

第二步:创建应用程序启动类

应用程序启动类是整个项目的入口点,负责初始化Spring容器和启动嵌入式Tomcat服务器。

这里采用编程方式启动Tomcat,而不是使用传统的@SpringBootApplication注解方式,以便更好地理解底层原理。

应用程序启动类 (Application.java)
package com.lihaozhe;
import com.lihaozhe.config.TomcatConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* <p>Spring Boot嵌入式Tomcat应用程序启动类</p>
* <p>开发思路:通过编程方式启动Spring容器和嵌入式Tomcat服务器,</p>
* <p>避免使用@SpringBootApplication注解,更好地理解底层实现原理</p>
* <p>开发过程:</p>
* <p>1. 创建Spring应用上下文,加载配置类</p>
* <p>2. 获取Tomcat配置Bean并启动嵌入式服务器</p>
* <p>3. 添加JVM关闭钩子,确保服务器优雅关闭</p>
* <p>4. 处理启动过程中的异常情况</p>
*
* @author 李昊哲 李胜龙
* @version 0.0.1
*/
public class Application {
/**
* <p>应用程序主方法,程序入口点</p>
* <p>开发思路:使用Spring的Java配置方式启动容器,</p>
* <p>然后手动启动嵌入式Tomcat服务器</p>
* <p>开发过程:</p>
* <p>1. 初始化Spring注解配置应用上下文</p>
* <p>2. 指定基础包路径进行组件扫描</p>
* <p>3. 刷新上下文以加载所有Bean</p>
* <p>4. 获取并启动Tomcat服务器</p>
* <p>5. 添加关闭钩子确保优雅关闭</p>
*
* @param args 命令行参数
*/
public static void main(String[] args) {
try {
// 创建Spring注解配置应用上下文
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext();
// 设置基础包路径,Spring将扫描这些包下的组件
context.scan("com.lihaozhe");
// 刷新应用上下文,加载所有配置和Bean
context.refresh();
// 从Spring容器中获取Tomcat配置Bean
TomcatConfig tomcatConfig = context.getBean(TomcatConfig.class);
// 启动嵌入式Tomcat服务器
tomcatConfig.startTomcat();
// 添加JVM关闭钩子,确保服务器能够优雅关闭
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
System.out.println("应用程序正在关闭...");
context.close(); // 关闭Spring容器
}));
System.out.println("应用程序启动成功!");
} catch (Exception e) {
// 捕获并处理启动过程中的异常
System.err.println("应用程序启动失败:" + e.getMessage());
e.printStackTrace();
System.exit(1); // 异常退出
}
}
}

第三步:配置Spring核心组件

Spring配置类负责定义应用程序的核心配置,包括组件扫描、Bean定义等。

这里使用Java配置方式替代传统的XML配置,提供更好的类型安全和可读性。

Spring核心配置类 (SpringConfig.java)
package com.lihaozhe.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* <p>Spring核心配置类</p>
* <p>开发思路:使用Java配置方式替代XML配置,</p>
* <p>提供类型安全的配置定义和更好的可读性</p>
* <p>开发过程:</p>
* <p>1. 使用@Configuration注解标记为配置类</p>
* <p>2. 配置组件扫描范围,自动发现Spring组件</p>
* <p>3. 提供默认构造方法,确保Spring能够正确实例化</p>
*
* @author 李昊哲 李胜龙
* @version 0.0.1
*/
// 标记此类为Spring配置类,替代XML配置文件
@Configuration
// 配置组件扫描,自动发现指定包下的Spring组件
@ComponentScan(basePackages = "com.lihaozhe")
public class SpringConfig {
/**
* <p>默认构造方法</p>
* <p>开发思路:提供显式的默认构造方法,</p>
* <p>确保Spring容器能够正确实例化配置类</p>
*/
public SpringConfig() {
// 构造方法体,目前为空
// Spring会自动处理配置类的初始化过程
}
}

第四步:配置Thymeleaf模板引擎

Thymeleaf是一个现代的服务器端Java模板引擎,能够处理HTML、XML、JavaScript、CSS等文件。

这里需要配置三个核心组件:模板解析器、模板引擎和视图解析器。

Thymeleaf配置类 (ThymeleafConfig.java)
package com.lihaozhe.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
import org.thymeleaf.spring6.SpringTemplateEngine;
import org.thymeleaf.spring6.view.ThymeleafViewResolver;
/**
* <p>Thymeleaf模板引擎配置类</p>
* <p>开发思路:配置Thymeleaf模板引擎的三个核心组件,</p>
* <p>实现模板文件的解析、处理和视图渲染功能</p>
* <p>开发过程:</p>
* <p>1. 配置模板解析器,指定模板文件位置和编码</p>
* <p>2. 配置模板引擎,集成Spring EL表达式</p>
* <p>3. 配置视图解析器,处理控制器返回的视图名称</p>
* <p>4. 设置字符编码和缓存策略</p>
*
* @author 李昊哲 李胜龙
* @version 0.0.1
*/
// 标记此类为Spring配置类
@Configuration
public class ThymeleafConfig {
/**
* <p>配置模板解析器Bean</p>
* <p>开发思路:创建ClassLoaderTemplateResolver,</p>
* <p>用于从classpath中加载模板文件</p>
* <p>开发过程:</p>
* <p>1. 设置模板前缀为templates/目录</p>
* <p>2. 设置模板后缀为.html</p>
* <p>3. 配置模板模式为HTML</p>
* <p>4. 设置字符编码为UTF-8</p>
* <p>5. 配置缓存策略(开发环境可关闭缓存)</p>
*
* @return 配置好的模板解析器实例
*/
// 声明此方法返回一个Spring管理的Bean
@Bean
public ClassLoaderTemplateResolver templateResolver() {
// 创建类加载器模板解析器
ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
// 设置模板文件前缀,指向resources/templates目录
templateResolver.setPrefix("templates/");
// 设置模板文件后缀,支持.html文件
templateResolver.setSuffix(".html");
// 设置模板模式为HTML,支持HTML5特性
templateResolver.setTemplateMode(TemplateMode.HTML);
// 设置字符编码为UTF-8,支持中文显示
templateResolver.setCharacterEncoding("UTF-8");
// 设置缓存为false,开发时便于调试(生产环境建议设为true)
templateResolver.setCacheable(false);
return templateResolver;
}
/**
* <p>配置模板引擎Bean</p>
* <p>开发思路:创建SpringTemplateEngine,</p>
* <p>集成Spring表达式语言和模板解析器</p>
* <p>开发过程:</p>
* <p>1. 创建Spring模板引擎实例</p>
* <p>2. 设置模板解析器</p>
* <p>3. 启用Spring EL表达式集成</p>
*
* @return 配置好的模板引擎实例
*/
@Bean
public SpringTemplateEngine templateEngine() {
// 创建Spring模板引擎
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
// 设置模板解析器,用于加载和解析模板文件
templateEngine.setTemplateResolver(templateResolver());
// 启用Spring EL表达式集成,支持Spring表达式语法
templateEngine.setEnableSpringELCompiler(true);
return templateEngine;
}
/**
* <p>配置视图解析器Bean</p>
* <p>开发思路:创建ThymeleafViewResolver,</p>
* <p>将控制器返回的逻辑视图名解析为实际模板文件</p>
* <p>开发过程:</p>
* <p>1. 创建Thymeleaf视图解析器</p>
* <p>2. 设置模板引擎</p>
* <p>3. 配置字符编码</p>
* <p>4. 设置视图名称和内容类型</p>
*
* @return 配置好的视图解析器实例
*/
@Bean
public ThymeleafViewResolver viewResolver() {
// 创建Thymeleaf视图解析器
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
// 设置模板引擎,用于处理模板渲染
viewResolver.setTemplateEngine(templateEngine());
// 设置字符编码为UTF-8,确保中文正确显示
viewResolver.setCharacterEncoding("UTF-8");
// 设置视图名称,支持逻辑视图名解析
viewResolver.setViewNames(new String[]{"*"});
// 设置内容类型为text/html
viewResolver.setContentType("text/html");
return viewResolver;
}
}

第五步:配置嵌入式Tomcat

嵌入式Tomcat配置是本项目的核心部分,负责创建和配置Tomcat服务器实例。

通过编程方式配置Tomcat,可以更好地理解Web服务器的工作原理。

嵌入式Tomcat配置类 (TomcatConfig.java)
package com.lihaozhe.config;
import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.startup.Tomcat;
import org.springframework.web.servlet.DispatcherServlet;
/**
* <p>嵌入式Tomcat配置类</p>
* <p>开发思路:通过编程方式配置和启动嵌入式Tomcat服务器,</p>
* <p>集成Spring MVC的DispatcherServlet,实现Web请求处理</p>
* <p>开发过程:</p>
* <p>1. 创建Tomcat实例并配置基本参数</p>
* <p>2. 创建Spring Web应用上下文</p>
* <p>3. 配置DispatcherServlet并注册到Tomcat</p>
* <p>4. 启动Tomcat服务器并处理异常</p>
*
* @author 李昊哲 李胜龙
* @version 0.0.1
*/
public class TomcatConfig {
/**
* <p>启动嵌入式Tomcat服务器</p>
* <p>开发思路:创建Tomcat实例,配置端口和上下文路径,</p>
* <p>然后集成Spring MVC的DispatcherServlet</p>
* <p>开发过程:</p>
* <p>1. 创建Tomcat实例并设置基本参数</p>
* <p>2. 创建临时目录作为Tomcat工作目录</p>
* <p>3. 创建Spring Web应用上下文</p>
* <p>4. 创建并配置DispatcherServlet</p>
* <p>5. 将DispatcherServlet添加到Tomcat上下文</p>
* <p>6. 启动Tomcat服务器并等待请求</p>
*/
public void startTomcat() {
try {
// 创建Tomcat实例
Tomcat tomcat = new Tomcat();
// 设置服务器端口号为8080
tomcat.setPort(8080);
// 设置主机名为localhost
tomcat.setHostname("localhost");
// 创建临时目录作为Tomcat工作目录
String tempDir = System.getProperty("java.io.tmpdir");
tomcat.setBaseDir(tempDir);
// 创建Tomcat上下文,设置上下文路径为根路径
Context context = tomcat.addContext("", tempDir);
// 创建Spring Web应用上下文
org.springframework.web.context.WebApplicationContext webContext =
org.springframework.web.context.ContextLoader.getCurrentWebApplicationContext();
// 如果Web上下文不存在,创建新的应用上下文
if (webContext == null) {
// 创建注解配置的Web应用上下文
org.springframework.web.context.support.AnnotationConfigWebApplicationContext wac =
new org.springframework.web.context.support.AnnotationConfigWebApplicationContext();
// 注册配置类
wac.register(SpringConfig.class, ThymeleafConfig.class);
// 设置上下文配置位置
wac.setConfigLocation("com.lihaozhe.config");
// 刷新上下文
wac.refresh();
webContext = wac;
}
// 创建DispatcherServlet实例
DispatcherServlet dispatcherServlet = new DispatcherServlet(webContext);
// 将DispatcherServlet添加到Tomcat上下文
Tomcat.addServlet(context, "dispatcherServlet", dispatcherServlet);
// 设置Servlet映射,将所有请求映射到DispatcherServlet
context.addServletMappingDecoded("/", "dispatcherServlet");
// 启动Tomcat服务器
tomcat.start();
// 输出启动成功信息
System.out.println("嵌入式Tomcat服务器已启动,访问地址:http://localhost:8080");
// 保持服务器运行,等待请求
tomcat.getServer().await();
} catch (LifecycleException e) {
// 捕获Tomcat启动异常
System.err.println("Tomcat启动失败:" + e.getMessage());
e.printStackTrace();
throw new RuntimeException("无法启动嵌入式Tomcat服务器", e);
}
}
}

第六步:创建控制器处理请求

控制器是MVC架构中的C部分,负责处理HTTP请求并返回相应的视图。

这里使用Spring MVC的注解来简化控制器开发。

请求处理控制器 (HelloController.java)
package com.lihaozhe.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
/**
* <p>请求处理控制器类</p>
* <p>开发思路:使用Spring MVC的@Controller注解创建控制器,</p>
* <p>通过@GetMapping处理HTTP GET请求,返回视图名称</p>
* <p>开发过程:</p>
* <p>1. 使用@Controller注解标记为控制器</p>
* <p>2. 使用@GetMapping映射根路径请求</p>
* <p>3. 向Model添加数据传递给视图</p>
* <p>4. 返回逻辑视图名称,由视图解析器解析</p>
*
* @author 李昊哲 李胜龙
* @version 0.0.1
*/
// 标记此类为Spring MVC控制器
@Controller
public class HelloController {
/**
* <p>处理根路径请求的方法</p>
* <p>开发思路:使用@GetMapping注解映射HTTP GET请求,</p>
* <p>向Model添加数据并返回视图名称</p>
* <p>开发过程:</p>
* <p>1. 使用@GetMapping("/")映射根路径</p>
* <p>2. 通过Model对象传递数据到视图</p>
* <p>3. 返回逻辑视图名称"index"</p>
* <p>4. 视图解析器将解析为templates/index.html</p>
*
* @param model Spring MVC模型对象,用于传递数据到视图
* @return 逻辑视图名称,由视图解析器解析为实际模板文件
*/
// 映射HTTP GET请求到根路径"/"
@GetMapping("/")
public String index(Model model) {
// 向模型添加消息数据,键为"msg",值为欢迎信息
model.addAttribute("msg", "欢迎使用Spring Boot嵌入式Tomcat项目!");
// 返回逻辑视图名称"index"
// ThymeleafViewResolver会将其解析为templates/index.html
return "index";
}
}

第七步:创建HTML模板文件

Thymeleaf模板文件位于resources/templates目录下,使用HTML5语法和Thymeleaf特有的属性来动态渲染内容。

首页模板 (index.html)
<!--
开发思路:使用Thymeleaf模板引擎创建动态HTML页面,
通过Thymeleaf表达式显示从控制器传递的数据
开发过程:
1. 定义HTML5文档结构
2. 引入Thymeleaf命名空间
3. 使用Thymeleaf表达式显示动态内容
4. 添加基本的页面样式
-->
<!DOCTYPE html>
  <!-- 引入Thymeleaf命名空间,支持th:前缀的属性 -->
      <html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
      <head>
        <!-- 字符编码设置,确保中文正确显示 -->
            <meta charset="UTF-8">
            <!-- 视口设置,支持响应式设计 -->
                <meta name="viewport" content="width=device-width, initial-scale=1.0">
                <!-- 页面标题 -->
                <title>Spring Boot 嵌入式Tomcat 示例</title>
                  <!-- 基本样式设置 -->
                    <style>
                      body {
                      font-family: 'Microsoft YaHei', Arial, sans-serif; /* 设置字体 */
                      margin: 0; /* 清除默认外边距 */
                      padding: 20px; /* 设置内边距 */
                      background-color: #f5f5f5; /* 背景色 */
                      }
                      .container {
                      max-width: 800px; /* 最大宽度 */
                      margin: 0 auto; /* 居中显示 */
                      background-color: white; /* 背景色 */
                      padding: 30px; /* 内边距 */
                      border-radius: 8px; /* 圆角 */
                      box-shadow: 0 2px 10px rgba(0,0,0,0.1); /* 阴影效果 */
                      }
                      h1 {
                      color: #333; /* 标题颜色 */
                      text-align: center; /* 居中对齐 */
                      margin-bottom: 30px; /* 底部外边距 */
                      }
                      .message {
                      font-size: 18px; /* 字体大小 */
                      color: #666; /* 文字颜色 */
                      text-align: center; /* 居中对齐 */
                      padding: 20px; /* 内边距 */
                      background-color: #f8f9fa; /* 背景色 */
                      border-radius: 5px; /* 圆角 */
                      border-left: 4px solid #007bff; /* 左边框 */
                      }
                    </style>
                  </head>
                  <body>
                      <div class="container">
                      <!-- 页面标题 -->
                      <h1>Spring Boot 嵌入式Tomcat 演示</h1>
                        <!-- 消息显示区域 -->
                            <div class="message">
                            <!-- 使用Thymeleaf表达式显示从控制器传递的消息 -->
                            <p th:text="${msg}">默认消息</p>
                            </div>
                            <!-- 项目信息 -->
                                <div style="margin-top: 30px; text-align: center; color: #999;">
                              <p>这是一个基于Spring Boot和嵌入式Tomcat的Web应用程序示例</p>
                              <p>技术栈:Spring Boot 3.x + JDK 25 + Thymeleaf</p>
                              </div>
                            </div>
                          </body>
                        </html>

运行和测试

编译和运行项目

项目开发完成后,可以通过以下步骤编译和运行:

  1. 编译项目
mvn clean compile
  1. 打包项目
mvn clean package
  1. 运行应用程序
java -jar target/tomcat-spring-1.0.0.jar
  1. 访问应用程序
    在浏览器中访问:http://localhost:8080

预期结果

成功启动后,浏览器将显示一个包含欢迎信息的页面,页面内容为:“欢迎使用Spring Boot嵌入式Tomcat项目!”

项目特点和优势

技术优势

本项目展示了现代Java Web开发的多个重要特性:

  1. 嵌入式容器:无需外部Tomcat服务器,简化部署流程
  2. Java配置:替代XML配置,提供更好的类型安全性
  3. 注解驱动:使用Spring注解简化开发
  4. 模板引擎:Thymeleaf提供自然的模板语法
  5. Maven构建:标准化的项目构建和依赖管理

学习价值

通过这个项目,开发者可以深入理解:

  • Spring Boot的自动配置原理
  • 嵌入式Web服务器的工作机制
  • MVC架构模式的实现方式
  • 现代Java Web开发的最佳实践

扩展建议

在掌握基础项目后,可以考虑以下扩展方向:

  1. 添加数据库集成:集成JPA和H2/MySQL数据库
  2. 实现RESTful API:添加JSON格式的API接口
  3. 安全认证:集成Spring Security进行用户认证
  4. 前端框架:集成Vue.js或React等现代前端框架
  5. 容器化部署:使用Docker进行容器化部署

总结

本文详细介绍了从零开始开发Spring Boot嵌入式Tomcat项目的完整过程,包括项目架构设计、开发思路、具体实现和运行测试。

通过这个项目,读者可以深入理解现代Java Web开发的核心概念和最佳实践,为进一步学习Spring生态系统打下坚实基础。

项目采用的技术栈都是当前业界主流的选择,具有良好的学习价值和实用性。

通过逐步扩展和完善,可以构建出功能完整的企业级Web应用程序。

posted @ 2025-12-14 08:01  gccbuaa  阅读(4)  评论(0)    收藏  举报