Skip to content

SpringBoot 学习笔记

1. SpringBoot 概述

1.1 SpringBoot 简介

Spring Boot 是由 Pivotal 团队提供的全新框架,旨在简化基于 Spring 框架的开发。它通过提供开箱即用的配置、自动配置依赖管理等功能,使得开发者能够快速构建独立的、生产级别的基于 Spring 的应用程序。

设计理念

  • 约定优于配置:遵循最佳实践,默认情况下使用推荐的设置,只有当需要自定义行为时才进行显式配置
  • 易于上手:降低了学习曲线,即使是对 Spring 不熟悉的开发者也能迅速掌握并开始开发工作
  • 模块化设计:允许开发者根据实际需求选择性地引入特定功能模块,避免不必要的依赖

适用场景

  • 微服务架构:Spring Boot 非常适合构建微服务,简化服务集成,容易与 Spring Cloud 结合
  • RESTful API 开发:内置对构建 RESTful Web 服务的支持,配合 Spring MVC 轻松创建高效 API
  • 企业级应用开发:凭借强大的生态系统和丰富的插件,成为开发复杂业务逻辑的理想选择
  • 快速原型开发:快速启动能力和简洁配置使其成为理想的快速迭代开发平台

1.2 SpringBoot 特性

核心特性

  • 自动化配置:提供大量"开箱即用"的默认配置选项,减少手动配置工作量
  • 启动器依赖:将常见库组合在一起,预设合理版本号,如 spring-boot-starter-web
  • 内嵌容器:支持直接嵌入 Tomcat、Jetty 或 Undertow 等 Servlet 容器
  • 开发工具:包括热部署、自动重启等特性,提高开发效率

优势

  • 提高生产力:减少样板代码和简化配置,专注于业务逻辑实现
  • 社区支持广泛:拥有庞大开发者社区和技术文档资源
  • 持续更新发展:不断改进完善,紧跟技术潮流

总结:简化开发、简化配置、简化整合、简化部署、简化监控、简化运维

2. SpringBoot 快速入门

2.1 创建 SpringBoot 项目

  1. 新建工程,导入启动器依赖:
xml
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>3.0.3</version>
    </dependency>
    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>
  1. 编写配置文件 application.properties
properties
# 数据库配置
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/demo?useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root

# MyBatis 配置
mybatis.mapper-locations=classpath:mappers/*.xml
mybatis.configuration.map-underscore-to-camel-case=true

# 服务器配置
server.port=8080
server.servlet.context-path=/
spring.web.resources.static-locations=classpath:/static/
  1. 创建启动类:
java
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

3. SpringBoot 场景启动器

3.1 启动器概念

Spring Boot 场景启动器(Starter)是简化依赖管理和配置的方式,包含构建特定类型应用程序所需的所有依赖项和自动配置。

命名规范

  • 官方启动器:spring-boot-starter-*
  • 第三方启动器:*-spring-boot-starter

3.2 启动器作用

  • 父工程管理:所有 SpringBoot 项目都继承 spring-boot-starter-parent,定义了大量 jar 包及版本号
  • 基启动器:每个场景启动器都导入 spring-boot-starter,包含基础依赖
  • 配置管理:包含默认配置信息、属性类和配置类

3.3 常用场景启动器

xml
<!-- 基启动器 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>

<!-- Web 启动器 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- MyBatis 启动器 -->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>3.0.3</version>
</dependency>

3.4 启动器工作原理

  • 属性类 (****Properties):配置文件信息读取到这些类作为属性值存储
  • 配置类 (****Configuration):读取属性类信息,动态判断配置是否生效
  • 配置优先级:应用配置 > 启动器默认配置
  • 设计原则:约定大于配置

4. SpringBoot 配置文件详解

4.1 配置文件类型

SpringBoot 支持:

  • application.properties (优先级最高)
  • application.yml
  • application.yaml (优先级最低)

4.2 YAML 语法

yaml
# 键值对
key: value

# 多级配置
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydb
    username: root
    password: secret

# 数组和列表
myapp:
  servers:
    - server1.example.com
    - server2.example.com
    - server3.example.com

# 或使用方括号
myapp:
  servers: [server1.example.com, server2.example.com, server3.example.com]

4.3 读取配置

使用 @Value 注解

java
@Value("${jdbc.datasource.url}")
private String url;

使用 @ConfigurationProperties

java
@Component
@ConfigurationProperties(prefix = "jdbc.datasource")
@Data
public class JdbcProperty {
    private String driverClassName;
    private String url;
    private String username;
    private String password;
}

5. @ConfigurationProperties 注解详解

5.1 基本使用

定义属性类

java
@Component
@ConfigurationProperties(prefix = "jdbc.datasource")
@Data
public class JdbcProperty {
    private String driverClassName;
    private String url;
    private String username;
    private String password;
}

在配置类中使用

java
@Configuration
public class MybatisConfig {

    @Autowired
    private JdbcProperty jdbcProperty;

    @Bean
    public DataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(jdbcProperty.getDriverClassName());
        dataSource.setUrl(jdbcProperty.getUrl());
        dataSource.setUsername(jdbcProperty.getUsername());
        dataSource.setPassword(jdbcProperty.getPassword());
        return dataSource;
    }
}

5.2 注意事项

  • 添加 spring-boot-configuration-processor 依赖启用配置处理
  • 通过 @Component@EnableConfigurationProperties 注册为 Bean
  • 可为属性设置默认值
  • 敏感信息建议加密存储

6. @SpringBootApplication 注解详解

6.1 注解组成

@SpringBootApplication 是三个注解的组合:

  • @SpringBootConfiguration:标识为配置类
  • @EnableAutoConfiguration:启用自动配置机制
  • @ComponentScan:自动扫描并注册组件

6.2 自定义配置

自定义扫描包

java
@SpringBootApplication(scanBasePackages = {"com.example.package1", "com.example.package2"})

排除自动配置

java
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})

7. 自动配置原理

7.1 核心机制

  • 条件化注解:如 @ConditionalOnClass@ConditionalOnMissingBean
  • 自动配置类:位于 org.springframework.boot.autoconfigure 包下
  • spring.factories:通过 META-INF/spring.factories 文件加载自动配置类
  • 类路径扫描:根据类路径中的依赖自动配置功能

7.2 自动配置过程

  1. Spring Boot 启动时扫描 spring.factories 文件
  2. 加载所有自动配置类
  3. 根据条件化注解判断是否应用配置
  4. 应用符合条件的自动配置

8. 自定义启动器开发

8.1 创建自定义启动器

项目结构

spring-starter/
├── src/main/java
│   └── com/at/
│       ├── RobotProperties.java
│       ├── RobotService.java
│       ├── RobotAutoConfiguration.java
│       └── EnableRobot.java
└── src/main/resources
    └── META-INF
        └── spring.factories

依赖配置

xml
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

8.2 核心代码

属性类

java
@ConfigurationProperties(prefix = "robot")
@Component
@Data
public class RobotProperties {
    private String name;
    private String age;
    private String email;
}

业务类

java
@Service
public class RobotService {
    @Autowired
    RobotProperties robotProperties;

    public String sayHello() {
        return "你好:名字:【"+robotProperties.getName()+"】;年龄:【"+robotProperties.getAge()+"】";
    }
}

自动配置类

java
@Import({RobotProperties.class, RobotService.class})
@Configuration
public class RobotAutoConfiguration {}

启用注解

java
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(RobotAutoConfiguration.class)
public @interface EnableRobot {}

配置文件META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

com.at.RobotAutoConfiguration

8.3 使用自定义启动器

引入依赖

xml
<dependency>
    <groupId>com.at</groupId>
    <artifactId>spring-starter</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

启用配置

java
@SpringBootApplication
@EnableRobot
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

配置属性

properties
robot.name=lucy
robot.age=20
robot.email=java@at.com

9. SpringBoot 日志应用

9.1 日志框架

Spring Boot 默认使用 Logback 作为日志框架,通过 SLF4J 作为日志抽象层。

9.2 日志级别

从低到高:

  • TRACE
  • DEBUG
  • INFO
  • WARN
  • ERROR

设置日志级别

properties
# 全局日志级别
logging.level.root=INFO

# 特定包日志级别
logging.level.com.example=DEBUG

9.3 使用日志

使用 LoggerFactory

java
Logger log = LoggerFactory.getLogger(TestSlf4j.class);
log.info("日志信息");

使用 @Slf4j 注解

java
@Slf4j
@SpringBootTest
public class TestSlf4j {
    @Test
    public void testSlf4j() {
        log.info("普通信息info");
        log.error("错误信息error");
    }
}

9.4 日志分组

properties
# 设置日志分组
logging.group.model=com.at.service,com.at.mapper
logging.group.controller=com.at.controller

# 设置分组日志级别
logging.level.model=debug
logging.level.controller=info

9.5 文件输出

properties
# 设置日志文件路径
logging.file.path=/path/to/logs/

# 设置日志文件名
logging.file.name=application.log

9.6 日志归档与切割

properties
# 设置单个日志文件大小
logging.logback.rollingpolicy.max-file-size=10MB

# 设置日志保存天数
logging.logback.rollingpolicy.max-history=7

# 设置总日志文件大小
logging.logback.rollingpolicy.total-size-cap=1GB

9.7 切换 Log4j2

排除默认日志依赖

xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<!-- 引入 Log4j2 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

10. SpringBoot 整合 SSM

10.1 项目配置

依赖配置

xml
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>3.0.3</version>
    </dependency>
    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
        <scope>runtime</scope>
    </dependency>
</dependencies>

配置文件

yaml
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/demo
    username: root
    password: root

mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.at.pojo
  configuration:
    map-underscore-to-camel-case: true
    auto-mapping-behavior: full

10.2 整合要点

MyBatis 配置

java
@Configuration
@MapperScan("com.at.mapper")
public class MybatisConfig {
}

静态资源配置

properties
# 自定义静态资源路径(会覆盖默认路径)
spring.web.resources.static-locations=classpath:/webapp/

拦截器配置

java
@Configuration
public class SpringMVCConfig implements WebMvcConfigurer {
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor1())
               .addPathPatterns("/interceptorController/testInterceptor");
    }
}

11. 环境配置与部署

11.1 Profiles 多环境配置

环境配置文件

  • application-dev.yml - 开发环境
  • application-test.yml - 测试环境
  • application-prod.yml - 生产环境

激活环境

yaml
spring:
  profiles:
    active: dev

命令行激活

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

11.2 项目部署

打包部署

bash
# 打包
mvn clean package

# 运行
java -jar target/app.jar

# 带参数运行
java -jar app.jar --server.port=8081 --spring.datasource.url=jdbc:mysql://localhost:3306/mydb

11.3 单元测试

常用注解

  • @Test - 测试方法
  • @BeforeEach - 每个测试前执行
  • @AfterEach - 每个测试后执行
  • @DisplayName - 设置展示名称

断言使用

java
@Test
@DisplayName("测试方法1")
public void testMethod1() {
    // 断言相等
    Assertions.assertEquals("success", returnValue());

    // 断言不为空
    Assertions.assertNotNull(returnValue());

    // 组合断言
    Assertions.assertAll(
        () -> Assertions.assertEquals("success", returnValue()),
        () -> Assertions.assertNotNull(returnValue())
    );
}

12. 其他特性

12.1 Banner 定制

自定义 Banner

  1. src/main/resources 下创建 banner.txt
  2. 使用在线工具生成 ASCII Art:https://www.bootschool.net/ascii
  3. 配置启用:spring.banner.location=classpath:banner.txt

12.2 启动方式

方式一(默认):

java
SpringApplication.run(Application.class, args);

方式二

java
SpringApplication app = new SpringApplication(Application.class);
app.setBannerMode(Banner.Mode.OFF);
app.run(args);

方式三

java
new SpringApplicationBuilder()
    .sources(Application.class)
    .bannerMode(Banner.Mode.OFF)
    .run(args);

12.3 事件驱动编程

定义事件

java
@Data
public class LoginSuccessEvent {
    private String username;
    public LoginSuccessEvent(String username) {
        this.username = username;
    }
}

发布事件

java
@RestController
public class UserController {
    @Autowired
    private ApplicationEventPublisher publisher;

    @RequestMapping("/login")
    public String loginIn(String username, String password) {
        // 发布登录成功事件
        publisher.publishEvent(new LoginSuccessEvent(username));
        return "登录成功";
    }
}

监听事件

java
@Service
public class CouponService {
    @Async
    @EventListener(LoginSuccessEvent.class)
    public void listenLoginSuccess(LoginSuccessEvent event) {
        addCoupon(event.getUsername());
    }

    public void addCoupon(String username) {
        log.info("给用户" + username + "发放优惠券");
    }
}

启用异步

java
@SpringBootApplication
@EnableAsync
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}