全栈学习 ——JavaWeb(八)SpringBoot
SpringBoot通过"约定优于配置"理念,大幅简化Spring应用开发。核心优势包括:1)自动配置(基于@Conditional和SPI机制);2)起步依赖(统一版本管理);3)嵌入式容器(独立运行)。实战演示了快速构建Web应用(HelloWorld)、整合MyBatis(@Mapper注解替代XML配置)及用户管理系统(SSM整合),对比传统Spring开发可减少90%
目录
一、SpringBoot 的核心价值:为什么需要 SpringBoot?
(1)@SpringBootApplication:启动类的 “三合一” 注解
(2)@EnableAutoConfiguration 的工作原理
三、SpringBoot 实战:从 0 到 1 创建 Web 应用
2. 第一个 SpringBoot 应用:Hello World
3. 配置文件:application.properties
(3)编写 Mapper 接口(代替了之前的Dao层/数据持久层)
4. Service 层(UserService.java)
5. Controller 层(UserController.java)
SpringBoot 是基于 Spring 框架的 “开箱即用” 式开发工具,它通过 “约定优于配置” 的理念,消除了传统 Spring 应用中繁琐的 XML 配置和依赖管理,让开发者能专注于业务逻辑。本文将从底层原理到实战应用,全面解析 SpringBoot 的核心机制,对比传统 Spring 开发模式,并通过项目测试展示其便捷性。
一、SpringBoot 的核心价值:为什么需要 SpringBoot?
1. 传统 Spring 开发的痛点
在学习 Spring、SpringMVC、MyBatis 时,我们需要手动完成大量配置工作,典型问题包括:
(1)依赖管理复杂
传统项目需手动维护依赖版本,极易出现版本冲突:
<!-- 传统Spring MVC项目的依赖(需精确匹配版本) -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.20</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.20</version> <!-- 必须与spring-webmvc版本一致 -->
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.7</version> <!-- 需与Spring版本兼容 -->
</dependency>
(2)配置繁琐
以 SpringMVC 为例,需编写web.xml、spring-mvc.xml等多个配置文件:
<!-- 传统SpringMVC的web.xml配置 -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- spring-mvc.xml中的视图解析器配置 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
(3)部署麻烦
传统项目需打包为 WAR 包,手动部署到 Tomcat 等容器中,无法独立运行。
2. SpringBoot 的解决方案
SpringBoot 通过三大核心特性解决上述问题:
- 自动配置:根据引入的依赖自动配置 Spring 组件(如引入spring-boot-starter-web后,自动配置 DispatcherServlet、Tomcat 等);
- 起步依赖:将常用依赖组合为 “starters”,一键引入(如spring-boot-starter-web包含 SpringMVC、Tomcat 等);
- 嵌入式容器:内置 Tomcat、Jetty 等容器,项目可直接打包为 JAR 包独立运行。
二、SpringBoot 底层原理:自动配置的实现机制
SpringBoot 的核心是 “自动配置”,其底层依赖 Spring 的@Conditional注解和 SPI(Service Provider Interface)机制。
1. 自动配置的核心流程
(1)@SpringBootApplication:启动类的 “三合一” 注解
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@SpringBootApplication是三个注解的组合:
- @ComponentScan:扫描当前包及子包的@Component、@Service等注解;
- @Configuration:标识当前类为配置类;
- @EnableAutoConfiguration:开启自动配置(最核心)。
(2)@EnableAutoConfiguration 的工作原理
1.加载自动配置类:
@EnableAutoConfiguration通过@Import(AutoConfigurationImportSelector.class)导入自动配置类。这些类定义在spring-boot-autoconfigure.jar的META-INF/spring.factories文件中:
# spring.factories中的部分内容
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.mybatis.MybatisAutoConfiguration
2.条件装配(@Conditional):
自动配置类需满足@Conditional注解的条件才会生效。例如DispatcherServletAutoConfiguration:
@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET) // 仅在Servlet web环境下生效
@ConditionalOnClass(DispatcherServlet.class) // 仅当类路径存在DispatcherServlet时生效
public class DispatcherServletAutoConfiguration {
// 自动配置DispatcherServlet
@Bean
@ConditionalOnMissingBean // 仅当容器中没有DispatcherServlet时才创建
public DispatcherServlet dispatcherServlet() {
return new DispatcherServlet();
}
}
3.配置优先级:
开发者自定义的配置(如@Bean)优先级高于自动配置,可覆盖默认值。
2. 起步依赖(Starter)的实现
起步依赖本质是 Maven 的依赖管理模块,通过pom.xml定义一组相关依赖。例如spring-boot-starter-web的核心依赖:
<!-- spring-boot-starter-web的依赖(简化版) -->
<dependencies>
<!-- SpringMVC核心 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<!-- 嵌入式Tomcat -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<!-- JSON处理 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
</dependencies>
引入spring-boot-starter-web后,Maven 会自动下载所有依赖,无需手动指定版本(版本由 SpringBoot 父工程统一管理)。
3. 嵌入式容器
SpringBoot 默认使用嵌入式 Tomcat,其依赖通过spring-boot-starter-tomcat引入。启动时,SpringBoot 通过代码启动 Tomcat:
// 嵌入式Tomcat启动的核心逻辑(简化)
public class TomcatWebServer implements WebServer {
private final Tomcat tomcat;
public TomcatWebServer(Tomcat tomcat) {
this.tomcat = tomcat;
initialize(); // 初始化Tomcat
}
@Override
public void start() {
tomcat.start(); // 启动Tomcat
}
}
这使得项目可直接通过java -jar命令运行,无需外部容器。
三、SpringBoot 实战:从 0 到 1 创建 Web 应用
1. 环境搭建(使用 Spring Initializr)
访问Spring Initializr,填写项目信息:
- 项目类型:Maven
- 语言:Java
- Spring Boot 版本:2.7.x(稳定版)
- 依赖:Web(Spring Web)
下载项目并导入 IDE(如 IDEA),项目结构如下:
src/
├── main/
│ ├── java/
│ │ └── com/example/demo/
│ │ └── DemoApplication.java // 启动类
│ └── resources/
│ ├── application.properties // 全局配置文件
│ ├── static/ // 静态资源(CSS、JS等)
│ └── templates/ // 模板文件(Thymeleaf等)
└── test/ // 测试代码
2. 第一个 SpringBoot 应用:Hello World
(1)编写 Controller
// 无需XML配置,直接通过注解定义控制器
@RestController // 等价于@Controller + @ResponseBody
public class HelloController {
// 映射GET请求到/hello
@GetMapping("/hello")
public String hello() {
return "Hello, SpringBoot!";
}
}
(2)启动应用
运行DemoApplication的main方法,控制台输出如下:
Tomcat started on port(s): 8080 (http)
Started DemoApplication in 2.34 seconds (JVM running for 2.89)
(3)测试
访问http://localhost:8080/hello,页面显示:
Hello, SpringBoot!
对比传统 SpringMVC:
实现相同功能,传统方式需编写web.xml、spring-mvc.xml等配置,而 SpringBoot 仅需一个控制器类,简化 90% 以上配置。
3. 配置文件:application.properties
SpringBoot 使用application.properties(或application.yml)统一管理配置,替代传统 XML 配置。
(1)修改服务器端口
# application.properties
server.port=8081 # 端口改为8081
(2)配置 SpringMVC
# 配置静态资源路径(默认已配置,可自定义)
spring.mvc.static-path-pattern=/static/**
spring.web.resources.static-locations=classpath:/static/
# 配置视图解析器(使用Thymeleaf时)
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
(3)自定义配置
# 自定义配置项
app.name=myapp
app.version=1.0.0
通过@Value注解注入自定义配置:
@RestController
public class ConfigController {
@Value("${app.name}")
private String appName;
@GetMapping("/config")
public String getConfig() {
return "应用名称:" + appName; // 输出:应用名称:myapp
}
}
4. 整合 Spring IOC 容器
SpringBoot 完全兼容 Spring 的 IOC 机制,可通过@Service、@Autowired等注解实现依赖注入。
(1)Service 层
@Service // 注册为Spring Bean
public class UserService {
public String getUsername() {
return "SpringBoot";
}
}
(2)Controller 层注入 Service
@RestController
public class UserController {
@Autowired // 自动注入UserService
private UserService userService;
@GetMapping("/user")
public String getUser() {
return "当前用户:" + userService.getUsername();
}
}
对比传统 Spring:
传统方式需在 XML 中配置<bean id="userService" class="com.example.service.UserService"/>,而 SpringBoot 通过@Service自动注册 Bean,无需额外配置。
5. 整合 MyBatis
通过mybatis-spring-boot-starter可快速整合 MyBatis,无需手动配置SqlSessionFactory等组件。
(1)添加依赖
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
(2)配置数据库连接
# application.properties
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123456
(3)编写 Mapper 接口(代替了之前的Dao层/数据持久层)
@Mapper // MyBatis的Mapper注解(替代传统XML配置)
public interface UserMapper {
@Select("SELECT username FROM user WHERE id = #{id}")
String findUsernameById(int id);
}
(4)Service 层调用 Mapper
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public String getUsernameById(int id) {
return userMapper.findUsernameById(id);
}
}
(5)测试
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/user/{id}")
public String getUserById(@PathVariable int id) {
return "用户名称:" + userService.getUsernameById(id);
}
}
对比传统 MyBatis:
传统方式需配置SqlSessionFactory、MapperScannerConfigurer等 Bean,而 SpringBoot 通过@Mapper注解和起步依赖自动完成配置。
四、项目实战:用户管理系统(整合 SSM)
实现包含 “查询用户、新增用户” 功能的系统,展示 SpringBoot 整合 Spring、SpringMVC、MyBatis 的便捷性。
1. 数据库表设计
CREATE TABLE user (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL,
age INT
);
2. 实体类(User.java)
public class User {
private Integer id;
private String username;
private Integer age;
// 省略getter、setter、toString
}
3. Mapper 接口(UserMapper.java)
@Mapper
public interface UserMapper {
@Insert("INSERT INTO user (username, age) VALUES (#{username}, #{age})")
@Options(useGeneratedKeys = true, keyProperty = "id") // 回填自增ID
void insert(User user);
@Select("SELECT * FROM user WHERE id = #{id}")
User selectById(int id);
@Select("SELECT * FROM user")
List<User> selectAll();
}
4. Service 层(UserService.java)
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public void addUser(User user) {
userMapper.insert(user);
}
public User getUserById(int id) {
return userMapper.selectById(id);
}
public List<User> getAllUsers() {
return userMapper.selectAll();
}
}
5. Controller 层(UserController.java)
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
// 新增用户
@PostMapping
public String addUser(@RequestBody User user) {
userService.addUser(user);
return "新增成功,ID:" + user.getId();
}
// 根据ID查询
@GetMapping("/{id}")
public User getUser(@PathVariable int id) {
return userService.getUserById(id);
}
// 查询所有
@GetMapping
public List<User> getAllUsers() {
return userService.getAllUsers();
}
}
6. 测试接口
使用 Postman 或 curl 测试接口:
- 新增用户:POST http://localhost:8080/api/users,请求体{"username":"test","age":20}
- 查询用户:GET http://localhost:8080/api/users/1
7. 单元测试
SpringBoot 提供@SpringBootTest简化测试:
@SpringBootTest
public class UserServiceTest {
@Autowired
private UserService userService;
@Test
public void testAddUser() {
User user = new User();
user.setUsername("test");
user.setAge(20);
userService.addUser(user);
Assert.assertNotNull(user.getId()); // 验证ID是否回填
}
}
五、SpringBoot 与传统 Spring 技术的对比
技术点 |
传统 Spring 开发 |
SpringBoot 开发 |
依赖管理 |
手动引入依赖,需匹配版本 |
起步依赖(Starter),自动管理版本 |
配置方式 |
大量 XML 配置(如applicationContext.xml) |
注解 +application.properties,零配置为主 |
容器部署 |
打包为 WAR,部署到外部 Tomcat |
内置容器,打包为 JAR,java -jar直接运行 |
Spring MVC 配置 |
需配置 DispatcherServlet、视图解析器等 |
自动配置,无需手动干预 |
MyBatis 整合 |
需配置 SqlSessionFactory、Mapper 扫描 |
@Mapper注解 + 起步依赖,自动配置 |
开发效率 |
配置繁琐,开发周期长 |
专注业务逻辑,开发效率提升 50% 以上 |
六、SpringBoot 的高级特性
1. profiles:多环境配置
通过application-{profile}.properties区分环境:
- application-dev.properties(开发环境)
- application-prod.properties(生产环境)
启动时指定环境:
java -jar demo.jar --spring.profiles.active=prod
2. Actuator:应用监控
添加依赖即可监控应用健康状态、接口信息等:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
访问http://localhost:8080/actuator/health查看健康状态。
3. 外部化配置
支持从环境变量、命令行参数、配置中心等多种来源读取配置,例如:
# 命令行参数覆盖配置
java -jar demo.jar --server.port=8082
七、总结:SpringBoot 的核心优势
SpringBoot 并非对 Spring 的替代,而是通过 “约定优于配置” 的思想简化了 Spring 应用的开发:
简化配置:自动配置替代 XML,开发者无需关注底层组件的组装;
提升效率:起步依赖和嵌入式容器让项目快速搭建和运行;
兼容生态:完全兼容 Spring 的 IOC、AOP、事务等核心功能;
易于扩展:通过自定义配置和@Conditional可灵活扩展自动配置。
掌握 SpringBoot 是现代 JavaWeb 开发的必备技能,它不仅简化了传统 SSM 框架的使用,也是微服务架构(如 Spring Cloud)的基础。
更多推荐
所有评论(0)