当前位置: 首页 > ops >正文

SpringBoot学习笔记(1)

1. SpingBoot概述

1.1 Web技术栈

Spring Framework 提供了两种主要的 Web 技术栈:Servlet Stack【基于 Spring MVC】和Reactive Stack【基于 Spring WebFlux】。它们在架构、执行模型和适用场景上存在显著差异。

🔁 Servlet Stack

✅ 特点

  • 阻塞式 I/O:每个请求由一个线程处理,直到响应完成。
  • 线程池模型:依赖线程池来处理并发请求,线程数受限。
  • 成熟稳定:生态完善,社区资源丰富。
  • 开发简便:基于命令式编程,易于理解和调试。

🚫 局限

  • 资源消耗大:高并发时需要大量线程,增加硬件资源消耗。
  • 扩展性受限:在高并发场景下,性能瓶颈明显。

Reactive Stack

✅ 特点

  • 非阻塞式 I/O:基于 Reactor 的 MonoFlux,实现异步处理。
  • 事件驱动模型:采用少量线程处理大量并发请求。
  • 高扩展性:适合高并发、实时性要求高的应用。
  • 支持响应式编程:更好地处理流式数据和背压控制。

🚫 局限

  • 学习曲线陡峭:需要掌握响应式编程理念。
  • 调试复杂:异步调用链调试相对困难。
  • 生态相对较新:部分第三方库可能不支持响应式。

1.2 SpringBoot简介

Spring Boot可以简单地创建独立的、生产级的基于 Spring 的应用程序,并且可以“直接运行”。对Spring平台和第三方库采取了约定优于配置的观点,因此可以轻松上手。大多数Spring Boot应用程序几乎不需要配置Spring。其特点如下:

  • 创建独立的 Spring 应用程序:无需依赖外部容器,应用可独立运行。
  • 直接嵌入 Tomcat、Jetty 或 Undertow:无需部署WAR文件。
  • 提供约定优于配置的“起步”依赖:简化构建配置。
  • 尽可能自动配置 Spring 和第三方库:减少手动配置。
  • 提供生产就绪的特性:如指标、健康检查和外部化配置。
  • 绝对不生成代码,且不需要 XML 配置:简化开发流程。

创建一个简单的SpringBoot项目的步骤如下:

  • 引入springboot和相关依赖

    <?xml version="1.0" encoding="UTF-8"?>
    <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"><modelVersion>4.0.0</modelVersion><!-- 项目基本信息 --><groupId>com.example</groupId><artifactId>demo</artifactId><version>1.0.0-SNAPSHOT</version><name>springboot-demo</name><description>Spring Boot Demo Project</description><!-- 继承 Spring Boot 父项目 --><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.3.3</version></parent><!-- 通用配置 --><properties><java.version>17</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding></properties><!-- 依赖管理 --><dependencies><!-- Web 支持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 测试支持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><!-- 构建配置 --><build><plugins><!-- 打包可执行 JAR --><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build>
    </project>
    
  • 编写主程序:主程序所在的包即为主包

    package com.person.boot;import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
    public class MainApplication {public static void main(String[] args) {SpringApplication.run(MainApplication.class, args);}
    }
    
  • 编写控制器

    package com.person.boot.controller;import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;@RestController
    public class HelloController {@GetMapping("/hello")public String sayHello(){return "Hello Spring Boot";}
    }
    
  • 编写配置文件:可选,集中式管理配置

    # 修改服务器端口
    server.port=8081
    

1.3 场景

Spring Boot 中,将 spring-boot-starter-web 称为“场景”,是一种对模块化依赖设计理念的通俗化表达。Spring Boot Starter是一组预定义的依赖集合,每个 Starter对应一个特定的开发场景,如 Web 开发、数据访问、安全等。这种设计旨在:

  • 简化依赖管理:用户无需手动添加多个零散的依赖。
  • 自动配置:根据Starter自动启用相关功能,如内嵌TomcatMVC配置。

Starter称为“场景”,是因为它代表了一种完整的、开箱即用的功能模块,直接对应实际开发中的某种需求场景。其它常见的场景如下:

Starter对应场景功能说明
spring-boot-starter-data-jpa数据访问场景【JPA + 数据库】集成 Hibernate、Spring Data JPA
spring-boot-starter-security安全场景提供认证、授权、加密等安全功能
spring-boot-starter-test测试场景提供 JUnit、Mockito、Spring Test 支持
spring-boot-starter-actuator监控运维场景提供健康检查、指标监控等运维功能

对于场景,在命名上有着以下区别:

  • 官方提供的场景:spring-boot-starter-*
  • 第三方提供场景:*-spring-boot-starter

对于插件spring-boot-maven-plugin,其作用是将应用及其所有依赖打包为可执行的Fat JAR,即包含内嵌Servlet容器,如Tomcat。其优势是无需外部容器,直接通过 java -jar 运行,在Linux系统上部署极其简单。

1.4 Spring Initializr

Spring InitializrSpring官方提供的 项目初始化工具,用于快速生成 Spring Boot 项目的基础结构。其核心作用是 简化项目的创建和配置流程,帮助开发者专注于业务开发而非环境搭建。生成内容如下:

my-project/
├── src/
│   ├── main/
│   │   ├── java/        # 源码目录
│   │   └── resources/   # 配置文件目录
│   └── test/           # 测试代码目录
├── pom.xml             # Maven 配置文件
└── .gitignore          # Git 忽略文件模板

在创建中可能会遇到以下错误:表明IntelliJ IDEA在尝试连接Spring Initializr以创建Spring Boot项目时失败。这通常与网络连接、代理设置或防火墙配置有关。

Initialization failed for 'https://start.spring.io/' Please check URL, network and proxy settings.
Error message: Cannot download 'https://start.spring.io/': Connection refused: no further information

解决方法如下:

  • 如果未启用VPN:将默认地址 https://start.spring.io 更改为 https://start.aliyun.com/
  • 启用了VPN
    • 导航至 File > Settings
    • 在左侧菜单中选择 Appearance & Behavior > System Settings > HTTP Proxy
    • 选择 Auto-detect proxy settings或手动配置代理。
    • 点击 Check connection,输入 https://start.spring.io,测试连接是否成功。

1.5 依赖管理机制

Maven项目中,Spring Boot 提供了一个名为 spring-boot-starter-parent 的父 POM。通过在项目的 pom.xml 中继承该父 POM,可以自动获得一组经过 Spring Boot 团队测试和验证的依赖版本。这意味着在添加依赖时,无需显式指定版本号,Maven 会根据父 POM 中的配置自动解析依赖版本,从而确保项目中各个库之间的兼容性和一致性。

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.3.3</version> <!-- 指定 Spring Boot 版本 -->
</parent>

如果需要覆盖某个依赖的默认版本:

  • 可以在 properties 中指定:

    <properties><jackson.version>2.12.3</jackson.version>
    </properties>
    
  • 采用maven的就近原则,如下:

    <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId<version>8.0.33</version>
    </dependency>
    

Spring Boot 提供了一系列以 spring-boot-starter- 开头的 Starter 依赖,这些是预定义的依赖集合,旨在简化特定功能的集成。例如,spring-boot-starter-web 包含了构建 Web 应用所需的所有依赖,如 Spring MVC、Tomcat、Jackson 等。通过引入相应的 Starter,开发者无需手动添加和管理各个相关依赖,从而提高开发效率并减少配置错误的可能性。

<dependencies><!-- 引入 Spring Boot Web Starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
</dependencies>

1.6 自动配置机制

package com.person.boot02;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class Boot02Application {public static void main(String[] args) {var ioc = SpringApplication.run(Boot02Application.class, args);// 获取并打印 Spring IOC 容器中所有注册的 Bean 名称String[] names = ioc.getBeanDefinitionNames();for (String name : names) {System.out.println(name);}}}
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration$DispatcherServletConfiguration
dispatcherServlet
spring.mvc-org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration$DispatcherServletRegistrationConfiguration
dispatcherServletRegistration
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration
org.springframework.boot.autoconfigure.task.TaskExecutorConfigurations$ThreadPoolTaskExecutorBuilderConfiguration
threadPoolTaskExecutorBuilder
......

这些Bean的存在表明Spring Boot已为你完成了MVC等基础设施搭建,开发者只需专注于业务逻辑。

Spring Boot 的包扫描规则是框架自动管理组件发现的核心机制,直接影响 @Component@Service@Controller 等注解的生效范围。

  • 默认扫描规则:默认扫描 @SpringBootApplication 注解标注的主类所在的包及其所有子包。
  • 自定义扫描路径
    • @SpringBootApplication(scanBasePackages = "com.example")
    • @ComponentScan("com.example")

配置绑定:Spring Boot 允许将配置文件中的配置项,自动映射到Java 类的属性上。这种机制称为配置绑定。如果某个配置项未在配置文件中显式设置,Spring Boot 会使用 类中定义的默认值,如果类属性没有初始值,则根据类型推断默认值。

1.7 底层常用注解

1.7.1 @ConfigurationSpringBootConfiguration

Spring Boot 应用中,@Configuration@SpringBootConfiguration 都用于标记配置类,但它们的用途和设计目标有所不同。

  • @Congfiguration:标记一个类为配置类,用于定义Bean,替代XML配置。

    • 核心功能

      • 定义 @Bean 方法,声明 Spring 容器管理的 Bean
      • 支持组件扫描,需配合 @ComponentScan
      • 可以与其他 @Configuration 类组合使用。
    • 使用场景

      • 通用配置:任何需要定义 Bean 的配置类。

      • 模块化配置:将不同功能的 Bean 拆分到多个 @Configuration 类中。

      • 第三方库集成:集成非 Spring Boot 管理的库时定义 Bean,如Mybatis

        @Configuration
        public class DatabaseConfig {@Beanpublic DataSource dataSource() {// 配置数据源return new HikariDataSource();}
        }
        
  • @SpringBootConfigurationSpring Boot 特有注解,标记主配置类,标识这是Spring Boot应用的入口配置。

    • 核心特性

      • 本质上是 @Configuration 的增强版,用于 Spring Boot 的自动配置机制。
      • 只能有一个:整个应用中应该只有一个类标记为 @SpringBootConfiguration
      • 通常通过 @SpringBootApplication 间接使用,因为 @SpringBootApplication 已经包含 @SpringBootConfiguration
    • 使用场景

      • 主启动类:Spring Boot 应用的入口类。

      • 测试配置:在集成测试中指定主配置类的位置。

        @SpringBootConfiguration
        @EnableAutoConfiguration
        @ComponentScan
        public class MyApplication {public static void main(String[] args) {SpringApplication.run(MyApplication.class, args);}
        }
        

上述两个注解的核心区别总结如下:

特性@Configuration@SpringBootConfiguration
所属框架Spring FrameworkSpring Boot
主要用途通用 Bean 定义标记 Spring Boot 主配置类
数量限制可定义多个整个应用只能有一个
自动配置支持不支持自动配置机制支持 Spring Boot 自动配置
测试上下文定位需手动指定配置类自动识别主配置类【通过 @SpringBootTest

1.7.2 @Bean@Scope

在 Spring 框架中,@Bean@Scope 是两个核心注解,用于控制 Bean 的定义和作用域。

  • @Bean:在配置类中显式声明一个方法返回的对象应注册为 Spring Bean。

    @Configuration
    public class AppConfig {@Bean(name = "dataSource")  // 指定Bean名称public DataSource dataSource() {HikariDataSource ds = new HikariDataSource();ds.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");ds.setUsername("root");ds.setPassword("123456");return ds;}
    }
    
  • @Scope:定义Bean的作用域,常见作用域如下:

    @Configuration
    public class ScopeConfig {@Bean@Scope("singleton")  // 默认值,可省略public SingletonService singletonService() {return new SingletonService();}@Bean@Scope("prototype")public PrototypeService prototypeService() {return new PrototypeService();}
    }
    
    作用域描述
    singleton默认作用域,整个容器中只有一个实例【单例】
    prototype每次请求时创建新实例
    request每个 HTTP 请求创建一个新实例【仅 Web 应用有效】
    session每个 HTTP Session 创建一个新实例【仅 Web 应用有效】
    application整个 ServletContext 生命周期中共享一个实例【仅 Web 应用有效】

1.7.3 @import@ComponentScan

@Import 注解用于将多个配置类组合起来,实现配置的模块化管理。其作用如下:

  • 配置聚合:将分散在多个类中的配置集中到主配置类。

  • 模块化加载:按需加载不同模块的配置,如数据源配置、安全配置等。

  • 替代 XML 的 <import>:实现类似 XML 配置中 <import resource="other-config.xml"/> 的效果。

    // 数据库配置模块
    @Configuration
    public class DatabaseConfig {@Beanpublic DataSource dataSource() {return new HikariDataSource();}
    }// 主配置类
    @Configuration
    @Import(DatabaseConfig.class) // 导入其他配置类
    public class AppConfig {// 其他Bean定义...
    }
    

@ComponentScan用于自动扫描指定包路径下的 Spring 组件,并将它们注册为 Spring 容器中的 Bean。

@Configuration
@ComponentScan("com.example") // 扫描com.example包及其子包
public class AppConfig {
}

1.7.4 条件注解

Spring 框架中,条件注解Conditional Annotations 允许根据特定条件动态控制 Bean 的注册或配置类的加载。这类注解在 Spring Boot 的自动配置中扮演核心角色。

**@Conditional**是所有条件注解的基注解,需配合实现 Condition 接口的类使用。

public class EnvCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {// 检查环境变量是否包含特定值String env = context.getEnvironment().getProperty("app.env");return "prod".equals(env);}
}@Configuration
@Conditional(EnvCondition.class)
public class ProdConfig {// 仅在生产环境生效的配置
}

**@Profile**根据激活的 Profile 加载配置。

@Configuration
@Profile("dev") // 仅在 dev 环境生效
public class DevConfig {@Beanpublic DataSource inMemoryDataSource() {return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2).build();}
}

Spring Boot 的派生条件注解如下:

注解作用描述
@ConditionalOnClass当类路径存在指定类时生效
@ConditionalOnMissingClass当类路径不存在指定类时生效
@ConditionalOnBean当容器中存在指定 Bean 时生效
@ConditionalOnMissingBean当容器中不存在指定 Bean 时生效
@ConditionalOnProperty当配置属性满足条件时生效
@ConditionalOnWebApplication当应用是 Web 应用时生效

1.7.5 @ConfigurationProperties@EnableConfigurationProperties

在 Spring Boot 中,@ConfigurationProperties@EnableConfigurationProperties 是用于简化外部化配置管理的核心注解。

  • @ConfigurationProperties:将配置文件如 application.properties/application.yml中的属性值绑定到 Java 对象。

    @Component
    @ConfigurationProperties(prefix = "app.mail") // 绑定app.mail开头的配置项
    @Validated
    public class MailConfigProperties {@NotBlankprivate String host;private int port = 25; // 默认值private boolean sslEnabled;// Getters and Setters// Lombok的@Getter/@Setter也可用
    }
    
    app.mail.host=smtp.example.com
    app.mail.port=587
    app.mail.ssl-enabled=true
    
  • @EnableConfigurationProperties:启用对 @ConfigurationProperties 注解类的处理,将配置类注册为 Spring 容器中的 Bean。使用场景如下:

    • 需要显式声明配置类,即非自动扫描包路径下的类。

    • 第三方库的配置类无法添加 @Component 注解时。

      @SpringBootApplication
      @EnableConfigurationProperties({MailConfigProperties.class, DatabaseConfigProperties.class})
      public class MyApplication {public static void main(String[] args) {SpringApplication.run(MyApplication.class, args);}
      }
      
      // 步骤1:定义配置类 无需@Component
      @ConfigurationProperties(prefix = "app.security")
      public class SecurityProperties {private String secretKey;private long tokenExpiration = 3600;// Getters/Setters
      }// 步骤2:启用配置类
      @Configuration
      @EnableConfigurationProperties(SecurityProperties.class)
      public class SecurityConfig {@Autowiredprivate SecurityProperties securityProps;@Beanpublic TokenService tokenService() {return new TokenService(securityProps.getSecretKey(), securityProps.getTokenExpiration());}
      }
      

1.8 自动装配原理

Spring Boot 的自动装配Auto-Configuration是基于“约定优于配置”的理念,自动根据项目的依赖和配置,为应用程序提供合理的默认设置。这意味着开发者无需手动配置常用组件,Spring Boot 会自动完成配置,减少了繁琐的 XML 或 Java 配置。

首先会导入场景,如spring-boot-starter-web,每个场景都会引入相关的所有依赖。但是所有场景都会引入一个核心场景spring-boot-starter,核心场景中引入了spring-boot-autoconfigure包,这个包里面包括所有的场景的所有配置。只要某个包下如aopjdbc的所有配置类都生效,那么SpringBoot官方的整合功能就能生效。

在这里插入图片描述

先简单看其中一个配置类,@AutoConfiguration本质上就是@Configruation,而它本质上就是@Component。这就出现一个问题,SpringBoot默认是扫描不到这些配置类的。

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package org.springframework.boot.autoconfigure.availability;import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.availability.ApplicationAvailability;
import org.springframework.boot.availability.ApplicationAvailabilityBean;
import org.springframework.context.annotation.Bean;@AutoConfiguration
public class ApplicationAvailabilityAutoConfiguration {public ApplicationAvailabilityAutoConfiguration() {}@Bean@ConditionalOnMissingBean({ApplicationAvailability.class})public ApplicationAvailabilityBean applicationAvailability() {return new ApplicationAvailabilityBean();}
}

这时就跟@SpringBootApplication注解有关了,该注解包含了以下三个注解:

  • @SpringBootConfiguration:标识当前类为配置类,是 @Configuration 的特化。

  • @EnableAutoConfiguration:启用自动装配功能。

    //
    // Source code recreated from a .class file by IntelliJ IDEA
    // (powered by FernFlower decompiler)
    //package org.springframework.boot.autoconfigure;import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Inherited;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    import org.springframework.context.annotation.Import;@Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @AutoConfigurationPackage
    @Import({AutoConfigurationImportSelector.class})
    public @interface EnableAutoConfiguration {String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";Class<?>[] exclude() default {};String[] excludeName() default {};
    }
    
  • @ComponentScan:启用组件扫描,默认扫描当前包及其子包。

@EnableAutoConfiguration注解是SpringBoot开启自动配置的核心,从源码中发现,通过

@Import({AutoConfigurationImportSelector.class})批量给容器中导入组件,这样SpringBoot就会默认加载spring-boot-autoconfigureMETA/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件下的所有配置类。

org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration
org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration
......

虽然导入了所有的配置类,但是不一定会全部生效。随便查看一个配置类的源码,不难发现都会有条件注解, 如果条件成立就可以通过@Bean给容器添加组件,这就是按需加载的核心。并且一些配置类有@EnableConfigurationProperties注解,这就实现了和配置文件的绑定。

import java.time.Duration;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.boot.autoconfigure.condition.ConditionMessage;
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.ImportRuntimeHints;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.util.ConcurrentReferenceHashMap;
import org.springframework.util.StringUtils;@AutoConfiguration
@ConditionalOnMissingBean(name = {"messageSource"},search = SearchStrategy.CURRENT
)
@AutoConfigureOrder(Integer.MIN_VALUE)
@Conditional({ResourceBundleCondition.class})
@EnableConfigurationProperties
@ImportRuntimeHints({MessageSourceRuntimeHints.class})
public class MessageSourceAutoConfiguration {private static final Resource[] NO_RESOURCES = new Resource[0];public MessageSourceAutoConfiguration() {}@Bean@ConfigurationProperties(prefix = "spring.messages")public MessageSourceProperties messageSourceProperties() {return new MessageSourceProperties();}@Beanpublic MessageSource messageSource(MessageSourceProperties properties) {ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();if (StringUtils.hasText(properties.getBasename())) {messageSource.setBasenames(StringUtils.commaDelimitedListToStringArray(StringUtils.trimAllWhitespace(properties.getBasename())));}if (properties.getEncoding() != null) {messageSource.setDefaultEncoding(properties.getEncoding().name());}messageSource.setFallbackToSystemLocale(properties.isFallbackToSystemLocale());Duration cacheDuration = properties.getCacheDuration();if (cacheDuration != null) {messageSource.setCacheMillis(cacheDuration.toMillis());}messageSource.setAlwaysUseMessageFormat(properties.isAlwaysUseMessageFormat());messageSource.setUseCodeAsDefaultMessage(properties.isUseCodeAsDefaultMessage());return messageSource;}......
}

1.9 配置文件

Spring Boot 中,application.propertiesapplication.yml【或 .yaml】都是用于配置应用程序属性的文件。它们功能相同,但在语法和使用习惯上有所不同。

  • application.properties:基于键值对,使用 key=value 的形式。通过点号表示属性的层级关系。

    server.port=8080
    spring.datasource.url=jdbc:mysql://localhost:3306/mydb
    spring.datasource.username=root
    spring.datasource.password=123456
    
  • application.yml / application.yaml:用 YAML格式,通过冒号和缩进表示属性的层级关系。

    server:port: 8080
    spring:datasource:url: jdbc:mysql://localhost:3306/mydbusername: rootpassword: 123456
    

application.propertiesapplication.yml文件都用于配置应用程序的属性。对于复杂对象,如数组、集合、Map、嵌套对象等的配置,Spring Boot 提供了灵活的支持。

  • 配置数组和集合:ListSetArray

    • application.properties

      my.list=apple,banana,orange
      
      @Value("${my.list}")
      private List<String> myList;@Component
      @ConfigurationProperties(prefix = "my")
      public class MyConfig {private List<String> list;// getters and setters
      }
      
    • application.yml

      my:list:- apple- banana- orange
      
  • 配置Map类型

    • application.properties

      my.map.key1=value1
      my.map.key2=value2
      
      @Component
      @ConfigurationProperties(prefix = "my")
      public class MyConfig {private Map<String, String> map;// getters and setters
      }
      
    • application.yml

      my:map:key1: value1key2: value2
      
  • 配置嵌套对象和对象列表

    • application.properties

      my.items[0].name=Item1
      my.items[0].value=10
      my.items[1].name=Item2
      my.items[1].value=20
      
      @Component
      @ConfigurationProperties(prefix = "my")
      public class MyConfig {private List<Item> items;// getters and setterspublic static class Item {private String name;private int value;// getters and setters}
      }
      
    • application.yml

      my:items:- name: Item1value: 10- name: Item2value: 20
      

yaml语法有着以下细节:

  • birthDay推荐写为birth-day

  • 文本:单引号不会转义,双引号会转义

  • 大文本

    • |开头,会保留格式

        description: |This is a multi-linestring that preservesline breaks.
      
    • >开头,会将换行符压缩为空格

        summary: >This is a multi-linestring that foldsline breaks into spaces.
      
  • truefalseyesno 等在 YAML 中会被解析为布尔值

  • 使用 --- 分隔多个文档

2. 日志配置

2.1 设置日志级别

Spring Boot 中,日志配置是应用开发和运维中的关键部分。Spring Boot 默认使用 SLF4J + Logback 作为日志框架,并提供了灵活的配置方式,支持通过配置文件或自定义日志配置文件进行设置。Spring Boot 支持以下日志级别,按优先级从低到高排列:

ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF

可以在 application.propertiesapplication.yml 文件中设置全局或特定包的日志级别。

# 设置根日志级别为 INFO
logging.level.root=INFO# 设置特定包的日志级别为 DEBUG
logging.level.com.example=DEBUG
logging:level:root: INFOcom.example: DEBUG

日志分组:Springboot中还内置了一些常用的日志分组,如websql

logging.group.tomcat=org.apache.catalina,org.apache.coyote,org.apache.tomcat
logging.level.tomcat=TRACE

2.2 文件输出

Spring Boot 允许自定义控制台和文件的日志输出格式。可以在配置文件中使用 logging.pattern.consolelogging.pattern.file 属性进行设置。

# 控制台日志输出格式
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n# 文件日志输出格式
logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n

常用的日志格式占位符包括:

  • %d{yyyy-MM-dd HH:mm:ss}:日志时间
  • %thread:线程名
  • %-5level:日志级别,左对齐
  • %logger{36}:日志记录器名称,最大长度为36
  • %msg:日志消息
  • %n:换行符

除了控制台输出,Spring Boot 还支持将日志输出到文件。可以通过以下配置实现:

# 设置日志文件的名称[相对路径]
logging.file.name=app.log# 或者设置日志文件的路径[绝对路径]
logging.file.path=/var/logs# 如果同时设置了 logging.file.name 和 logging.file.path,只有 logging.file.name 会生效

2.3 日志滚动

# 指定日志文件名称
logging.file.name=logs/myapp.log# 设置滚动日志文件的命名模式[按日期和索引]
logging.pattern.rolling-file-name=logs/myapp-%d{yyyy-MM-dd}.%i.log# 设置单个日志文件的最大大小
logging.file.max-size=10MB# 设置保留的历史日志文件的最大数量
logging.file.max-history=30# 设置所有日志文件的总大小上限
logging.file.total-size-cap=1GB

对于更复杂的日志配置需求,可以使用日志框架的配置文件,如 logback-spring.xml。将该文件放置在 src/main/resources 目录下,Spring Boot 会自动加载。如下述实现了:

  • 日志文件按天归档,文件名包含日期和索引号。

  • 每个日志文件最大为 10MB,超过后自动切割。

  • 归档的日志文件将被压缩为 .gz 格式。

  • 最多保留最近 30 天的日志文件,且总大小不超过 1GB。

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration><property name="LOG_PATH" value="logs"/><property name="LOG_FILE" value="${LOG_PATH}/app.log"/><property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"/><appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${LOG_FILE}</file><encoder><pattern>${LOG_PATTERN}</pattern></encoder><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><!-- 日志文件名格式:app-2025-05-06.0.log.gz --><fileNamePattern>${LOG_PATH}/app-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern><!-- 单个日志文件最大大小 --><maxFileSize>10MB</maxFileSize><!-- 最多保留30天的日志 --><maxHistory>30</maxHistory><!-- 总日志文件大小上限 --><totalSizeCap>1GB</totalSizeCap></rollingPolicy></appender><root level="INFO"><appender-ref ref="ROLLING_FILE"/></root>
    </configuration>
    
http://www.xdnf.cn/news/4509.html

相关文章:

  • 【信奥数学基础】最小公倍数与不等式证明
  • Docker 容器化部署深度研究与发展趋势
  • 【数据结构】单链表
  • Qt开发经验 --- 避坑指南(6)
  • Android接入国标平台:工业现场级的GB28181移动端接入实践
  • ps信息显示不全
  • 【纯小白博客搭建】Hugo+Github博客部署及主题(stack)美化等界面优化记录
  • 基于STM32、HAL库的ZMOD4410AI1R 气体传感器驱动程序设计
  • qwen2.5vl
  • 考研数据结构之树形查找:二叉排序树、平衡二叉树与红黑树(包含真题解析)
  • 使用 Couchbase Analytics Service 的典型步骤
  • 【面板数据】公开整理-各省刑事案件统计数据集(2011-2023年)
  • Java01-初识Java
  • C 语言 第六章 结构体(1)
  • 短词匹配:拼音相似度
  • LeetCode热题100--73.矩阵置零--中等
  • C语言初阶--数组
  • GSENSE2020BSI sCMOS科学级相机主要参数及应用场景
  • 探针卡的类型及其在半导体测试中的应用
  • Java高频面试之并发编程-13
  • 奥威BI:AI驱动的智能财务分析革新,重塑企业决策新范式
  • 深入探索 Spark RDD 行动算子:功能解析与实战应用
  • Python基础语法(上)
  • 从图灵机到量子计算:逻辑可视化的终极进化
  • 基于C++实现(控制台)交通咨询系统
  • C语言指针用法详解
  • 切片和边缘计算技术分析报告
  • 【今日三题】跳台阶扩展问题(找规律) / 包含不超过两种字符的最长子串 / 字符串的排列(回溯—全排列)
  • 架设手游使用游戏盾SDK怎么提升网络速度?
  • 【ROS2】Nav2源码之行为树定义、创建、加载