笔记 笔记
首页
  • 开发工具
  • Java Web
  • Java 进阶
  • 容器化技术
  • Java 专栏

    • Java 核心技术面试精讲
    • Java 业务开发常见错误 100 例
  • 数据库专栏

    • MySQL 实战 45 讲
    • Redis 核心技术与实战
  • 安全专栏

    • OAuth 2.0 实战课
  • 计算机系统
  • 程序设计语言
  • 数据结构
  • 知识产权
  • 数据库
  • 面向对象
  • UML
  • 设计模式
  • 操作系统
  • 结构化开发
  • 软件工程
  • 计算机网络
  • 上午题错题
在线工具 (opens new window)

EasT-Duan

Java 开发
首页
  • 开发工具
  • Java Web
  • Java 进阶
  • 容器化技术
  • Java 专栏

    • Java 核心技术面试精讲
    • Java 业务开发常见错误 100 例
  • 数据库专栏

    • MySQL 实战 45 讲
    • Redis 核心技术与实战
  • 安全专栏

    • OAuth 2.0 实战课
  • 计算机系统
  • 程序设计语言
  • 数据结构
  • 知识产权
  • 数据库
  • 面向对象
  • UML
  • 设计模式
  • 操作系统
  • 结构化开发
  • 软件工程
  • 计算机网络
  • 上午题错题
在线工具 (opens new window)

购买兑换码请添加

添加时候请写好备注,否则无法通过。

  • Maven

  • Bootstrap

  • Spring

  • Spring MVC

  • MyBatis

  • JUnit

  • GitFlow 工作流指南

  • SpringBoot

    • SpringBoot3-快速入门
      • 前置
        • 前置条件
        • 前置知识
      • 项目创建
      • 自动装配
        • 默认扫描规则
        • 配置默认值
        • 按需加载自动配置
        • @SpringBootApplication
        • XXXAutoConfiguration
      • 核心组件
        • 组件注册
        • 条件注解
        • @ConditionalOnXxx
        • 属性绑定
        • @ConfigurationProperties
        • @EnableConfigurationProperties
        • 复杂条件
        • 细节
      • 日志配置
        • 默认配置
        • 日志级别
        • 日志分组
        • 文件输出
        • 文件归档与滚动切割
        • 自定义配置
        • 切换日志组合
        • 最佳实战
    • SpringBoot3-Web开发
    • SpringBoot3-数据访问
    • SpringBoot3-基础特性
    • SpringBoot3-核心原理
    • SpringBoot3-场景集成
  • Reactor

  • 微服务

  • Java Web
  • SpringBoot
EasT-Duan
2024-09-05
目录

SpringBoot3-快速入门

欢迎来到我的 ChatGPT 中转站,极具性价比,为付费不方便的朋友提供便利,有需求的可以添加左侧 QQ 二维码,另外,邀请新用户能获取余额哦!最后说一句,那啥:请自觉遵守《生成式人工智能服务管理暂行办法》。

# 前置

注意

这里以SpringBoot3为例,SpringBoot2大部分也是通用的

# 前置条件

  • Java17
  • Spring、SpringMVC
  • Maven、Gradle

# 前置知识

首先学习 Spring 相关的知识 Spring (opens new window)、SpringMVC (opens new window)。

不学上面的内容也可以上手 SpringBoot,但是 SpringBoot 的核心知识离不开 Spring 和 SpringMVC,所以还是推荐看看。

# 项目创建

两种创建方式

  1. 创建一个普通的 Maven 工程,然后增加 <parent> 标签,然后导入 web、test 等需要的依赖。
  2. 通过 Spring Initializr (opens new window) 创建(如果使用了 IDEA 开发工具也可以在创建项目时选择 Spring Initializr)。

# 自动装配

通过下面的代码可以查看 SpringBoot 在启动的时候加载了多少个类。

public static void main(String[] args) {
    //var:java10 局部变量类型的自动推断
    var ioc = SpringApplication.run(MainApplication.class, args);
    //1、获取容器中所有组件的名字
    String[] names = ioc.getBeanDefinitionNames();
    //2、挨个遍历:
    // dispatcherServlet、beanNameViewResolver、characterEncodingFilter、multipartResolver
    // SpringBoot把以前配置的核心组件现在都给我们自动配置好了。
    for (String name : names) {
        System.out.println(name);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12

# 默认扫描规则

  1. @SpringBootApplication 标注的类就是主程序类。

  2. SpringBoot 只会扫描主程序所在的包及其下面的子包,自动的 component-scan 功能

  3. 自定义扫描路径

    • @SpringBootApplication(scanBasePackages = "com.dfd")
    • @ComponentScan("com.dfd") 直接指定扫描的路径

# 配置默认值

配置文件的所有配置项是和某个类的对象值进行一一绑定的。

绑定了配置文件中每一项值的类:属性类。简单来说就是能够在 application.properties 或者 application.yml 中配置的属性。

比如:

  • ServerProperties 绑定了所有 Tomcat 服务器有关的配置

  • MultipartProperties 绑定了所有文件上传相关的配置

参照官方文档 (opens new window):或者参照绑定的属性类。

# 按需加载自动配置

场景启动器除了会导入相关功能依赖,导入一个 spring-boot-starter ,所有的 starter 后缀包都会引入这个依赖。

spring-boot-starter 导入了一个包 spring-boot-autoconfigure 。包里面都是各种场景的 AutoConfiguration 自动配置类

虽然全场景的自动配置都在 spring-boot-autoconfigure 这个包,但是不是全都开启的。具体的逻辑是:

public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
		ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
	@Override
	public void process(AnnotationMetadata annotationMetadata, DeferredImportSelector deferredImportSelector) {
		Assert.state(deferredImportSelector instanceof AutoConfigurationImportSelector,
					() -> String.format("Only %s implementations are supported, got %s",
							AutoConfigurationImportSelector.class.getSimpleName(),
							deferredImportSelector.getClass().getName()));
		AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector) deferredImportSelector).getAutoConfigurationEntry(annotationMetadata);
		this.autoConfigurationEntries.add(autoConfigurationEntry);
		for (String importClassName : autoConfigurationEntry.getConfigurations()) {
			this.entries.putIfAbsent(importClassName, annotationMetadata);
		}
	}

// 这段代码中会加载META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports所有的配置项,然后过滤掉没有引用到的配置
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
		if (!isEnabled(annotationMetadata)) {
			return EMPTY_ENTRY;
		}
		AnnotationAttributes attributes = getAttributes(annotationMetadata);
		List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
		configurations = removeDuplicates(configurations); //去重
		Set<String> exclusions = getExclusions(annotationMetadata, attributes);// 获取排除项
		checkExcludedClasses(configurations, exclusions);
         // 如果在启动类中配置了排除项,在这里也会将写的排除类移除 
		configurations.removeAll(exclusions);
         // 这里会过滤掉所有未使用到的配置
		configurations = getConfigurationClassFilter().filter(configurations);
		fireAutoConfigurationImportEvents(configurations, exclusions);
		return new AutoConfigurationEntry(configurations, exclusions);
}
     // 这个方法会根据@ConditionalOnxxx注解中的配置来过滤
	List<String> filter(List<String> configurations) {
		long startTime = System.nanoTime();
		String[] candidates = StringUtils.toStringArray(configurations);
		boolean skipped = false;
		for (AutoConfigurationImportFilter filter : this.filters) {
			boolean[] match = filter.match(candidates, this.autoConfigurationMetadata);
			for (int i = 0; i < match.length; i++) {
				if (!match[i]) {
					candidates[i] = null;
					skipped = true;
				}
			}
		}
		if (!skipped) {
			return configurations;
		}
		List<String> result = new ArrayList<>(candidates.length);
		for (String candidate : candidates) {
			if (candidate != null) {
				result.add(candidate);
			}
		}
		if (logger.isTraceEnabled()) {
			int numberFiltered = configurations.size() - result.size();
			logger.trace("Filtered " + numberFiltered + " auto configuration class in "
					+ TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime) + " ms");
		}
		return result;
	}
}            
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

每一个自动配置类,都有条件注解 @ConditionalOnxxx ,只有条件成立,才能生效。

# @SpringBootApplication

点开这个注解后可以看到这个注解的详情

//指定这个注解只能应用于类型(类、接口、枚举)。
@Target(ElementType.TYPE)
//指定这个注解在运行时保留,可以通过反射来访问。
@Retention(RetentionPolicy.RUNTIME)
//表示这个注解应该被 Javadoc 工具记录。
@Documented
//允许子类继承父类的注解。
@Inherited
//指示一个类提供 Spring Boot 应用程序的配置。这是 @Configuration 的特殊形式。
@SpringBootConfiguration
//启用 Spring Boot 的自动配置机制(核心)。它会根据类路径中的 jar 依赖为项目自动配置 Spring 应用程序。
@EnableAutoConfiguration
//自动扫描并注册被 @Component、@Service、@Repository、@Controller 等注解修饰的 Bean。
///这里定义了两个排除过滤器:
////TypeExcludeFilter:用于排除特定类型的 Bean。
////AutoConfigurationExcludeFilter:用于排除自动配置类。
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# XXXAutoConfiguration

在 autoconfigure 下可以看到很多的包下都以 AutoConfiguration 结尾的类,类中基本都使用了 @EnableConfigurationProperties(ServerProperties.class) 这样的注解,这是用来把配置文件中配的指定前缀的属性值封装到 xxxProperties 属性类中,这些都可以在 application.properties 中进行配置。

# 核心组件

# 组件注册

@Configuration、@SpringBootConfiguration

@Bean、@Scope

@Controller、 @Service、@Repository、@Component

@Import

@ComponentScan

步骤:

  1. @Configuration 编写一个配置类。

  2. 在配置类中,自定义方法给容器中注册组件。配合 @Bean。

  3. 或使用 @Import 导入第三方的组件。

# 条件注解

笔记

如果注解指定的条件成立,则触发指定行为。

# @ConditionalOnXxx

  • @ConditionalOnClass:如果类路径中存在这个类,则触发指定行为。
  • @ConditionalOnMissingClass:如果类路径中不存在这个类,则触发指定行为。
  • @ConditionalOnBean:如果容器中存在这个 Bean(组件),则触发指定行为。
  • @ConditionalOnMissingBean:如果容器中不存在这个 Bean(组件),则触发指定行为。
/**
 * 来测试不同的@ConditionalOnBean,如果项目中存在一个StringRedis的Bean组件,那么就加载redisTemplate1否则就加载redisTemplate2
 * Redis配置类
 * @author Fengdong.Duan
 * @create 2024/6/25 下午1:43
 */
@Configuration
public class RedisConfig {


    @Bean
    @ConditionalOnBean(name = "StringRedis")
    public RedisTemplate<String, Object> redisTemplate1(RedisConnectionFactory factory) {
        // 创建 RedisTemplate 对象
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        // 设置 RedisConnection 工厂。它就是实现多种 Java Redis 客户端接入的秘密工厂。感兴趣的胖友,可以自己去撸下。
        template.setConnectionFactory(factory);
        // 使用 String 序列化方式,序列化 KEY 。
        template.setKeySerializer(RedisSerializer.string());
        template.setHashKeySerializer(RedisSerializer.string());
        // 使用 JSON 序列化方式(库是 Jackson ),序列化 VALUE 。
        template.setValueSerializer(buildRedisSerializer());
        template.setHashValueSerializer(buildRedisSerializer());
        return template;
    }


    @Bean
    @ConditionalOnMissingBean(name = "StringRedis")
    public RedisTemplate<String, Object> redisTemplate2(RedisConnectionFactory factory) {
        // 创建 RedisTemplate 对象
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        // 设置 RedisConnection 工厂。它就是实现多种 Java Redis 客户端接入的秘密工厂。感兴趣的胖友,可以自己去撸下。
        template.setConnectionFactory(factory);
        return template;
    }



    private RedisSerializer<?> buildRedisSerializer() {
        RedisSerializer<Object> json = RedisSerializer.json();
        // 解决 LocalDateTime 的序列化
        ObjectMapper objectMapper = (ObjectMapper) ReflectUtil.getFieldValue(json, "mapper");
        objectMapper.registerModules(new JavaTimeModule());
        return json;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

# 属性绑定

# @ConfigurationProperties

声明组件的属性和配置文件哪些前缀开始项进行绑定。

将容器中任意组件(Bean!!!!!)的属性值和配置文件的配置项的值进行绑定

  • 给容器中注册组件(@Component、@Bean)。
  • 使用 @ConfigurationProperties 声明组件和配置文件的哪些配置项进行绑定。
## 在application.yml中配置相关属性值
user:
  id: 1
  name: 东东
  age: 18
1
2
3
4
5
@Data
public class User {
    private Long id;
    private String name;
    private int age;
}

@Configuration
public class AppConfig {
    
    @Bean//或者在User类上注明@Component
    @ConfigurationProperties(prefix = "user")//标注在User类上也可
    public User user() {
        return new User();
    }
}

// 在IOC容器中就可以看到包含了自定义属性值的User对象信息了
var ioc = SpringApplication.run(MainApplication.class, args);
User user = ioc.getBean(User.class);
System.out.println(user);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# @EnableConfigurationProperties

快速注册注解。

** 场景:**SpringBoot 默认只扫描自己主程序所在的包。如果导入第三方包,即使组件上标注了 @Component、@ConfigurationProperties 注解也没用。因为组件都扫描不进来,此时使用这个注解就可以快速进行属性绑定并把组件注册进容器。

@Data
@ConfigurationProperties(prefix = "user")	//如果User没有放入到Bean容器中这里是会有报错提示的
public class User {
    private Long id;
    private String name;
    private int age;
}

@Configuration
@EnableConfigurationProperties(User.class) // 自动绑定到User对象上
public class AppConfig {
}
1
2
3
4
5
6
7
8
9
10
11
12

# 复杂条件

@Component
@ConfigurationProperties(prefix = "person")
@Data 
public class Person {
    private String name;
    private Integer age;
    private Date birthDay;
    private Boolean like;
    private Child child; //嵌套对象
    private List<Dog> dogs; //数组(里面是对象)
    private Map<String,Cat> cats; //表示Map
}

@Data
public class Dog {
    private String name;
    private Integer age;
}

@Data
public class Child {
    private String name;
    private Integer age;
    private Date birthDay;
    private List<String> text; //数组
}

@Data
public class Cat {
    private String name;
    private Integer age;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
person:
  name: 张三
  age: 18
  birthDay: 2010/10/10 12:12:12
  like: true
  child:
    name: 李四
    age: 20
    birthDay: 2018/10/10
    text: ["abc","def"]
  dogs:
    - name: 小黑
      age: 3
    - name: 小白
      age: 2
  cats:
    c1:
      name: 小蓝
      age: 3
    c2: {name: 小绿,age: 2} #对象也可用{}表示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

提供一种 properties 格式的写法

person.name=张三
person.age=18
person.birthDay=2010/10/12 12:12:12
person.like=true
person.child.name=李四
person.child.age=12
person.child.birthDay=2018/10/12
person.child.text[0]=abc
person.child.text[1]=def
person.dogs[0].name=小黑
person.dogs[0].age=3
person.dogs[1].name=小白
person.dogs[1].age=2
person.cats.c1.name=小蓝
person.cats.c1.age=3
person.cats.c2.name=小灰
person.cats.c2.age=2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 细节

  1. birthDay 推荐写为 birth-day
点击查看
  1. 命名约定:在配置文件中,通常推荐使用 > 命名约定:在配置文件中,通常推荐使用 kebab-case(短横线命名法)。这种命名方式被认为更易读,特别是对于长的属性名。
  2. 一致性:使用 kebab-case 可以保持配置文件中命名风格的一致性。Spring Boot 的许多内置属性也使用这种风格(例如 server.servlet.context-path )。
  3. 松散绑定:Spring Boot 支持松散绑定(relaxed binding),这意味着无论你在配置文件中使用 birth-day 、 birthDay 还是 birth_day ,它都能正确地映射到 Java 类中的 birthDay 属性。但是,为了保持一致性和可读性,推荐使用 kebab-case。
  4. 避免歧义:在某些情况下,camelCase 可能会导致歧义。例如, userID 和 userId 在某些系统中可能被视为不同的属性。使用 user-id 可以避免这种潜在的问题。
  5. 工具支持:一些 YAML 处理工具和编辑器对 kebab-case 的支持更好,可能会提供更好的自动完成和验证功能。
  6. 国际化考虑: 对于非英语母语的开发者来说,kebab-case 可能更容易理解和记忆。
user:
  birth-day: 1990-01-01
  first-name: John
  last-name: Doe
1
2
3
4
  1. 文本
  • 单引号不会转义【\n 则为普通字符串显示】。
  • 双引号会转义【\n 会显示为换行符】。
message:
  single-quote: 'This is a single-quoted string.\nThis will not create a new line.' ### 这个会显示一行
  double-quote: "This is a double-quoted string.\nThis will create a new line." ### 这个会显示两行
1
2
3
  1. 大文本
  • | 开头,大文本写在下层,保留文本格式,换行符正确显示。
  • > 开头,大文本写在下层,折叠换行符。
preserve-format: |
  This is a multi-line text.
  It will preserve line breaks and formatting.
  Each line will appear as written here.

fold-newlines: >
  This is also a multi-line text.
  However, it will fold newlines.
  This entire block will appear as a single line,
  with spaces where line breaks were.
1
2
3
4
5
6
7
8
9
10
  1. 多文档合并
  • 使用 --- 可以把多个 yaml 文档合并在一个文档中,每个文档区依然认为内容独立。
---
## 文档 1
spring:
  profiles: development
server:
  port: 8080

---
## 文档 2
spring:
  profiles: production
server:
  port: 80

---
## 文档 3
logging:
  level:
    root: INFO
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 日志配置

Spring 使用 commons-logging 作为内部日志,但底层日志实现是开放的。可对接其他日志框架。Spring 5 及以后 commons-logging 被 Spring 直接自己写了。

支持 jul , log4j2 , logback (默认)。SpringBoot 提供了默认的控制台输出配置,也可以配置输出为文件。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-logging</artifactId>
</dependency>
1
2
3
4

# 默认配置

默认使用了 logback + slf4j 组合作为默认底层日志,Spring Boot 使用 LoggingApplicationListener 来配置日志系统。这个监听器在 SpringApplication 启动过程中的早期阶段就会被触发。所以,它不遵循标准的自动配置模式。

默认的日志输出格式

2024-06-25T16:41:59.774+08:00  INFO 13500 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8881 (http) with context path ''
2024-06-25T16:41:59.786+08:00  INFO 13500 --- [           main] com.dfd.spring.demo.MainApplication      : Started MainApplication in 3.273 seconds (process running for 4.31)
1
2

从前到后的顺序是:

  • 时间和日期:毫秒级精度。
  • 日志级别:ERROR, WARN, INFO, DEBUG, or TRACE。
  • 进程 ID。
  • ---:消息分割符。
  • 线程名:使用 [] 包含。
  • Logger 名:通常是产生日志的类名。
  • 消息:日志记录的内容。

logback 没有 FATAL 级别,对应的是 ERROR。

通过 logging.pattern.console 属性可以修改日志输出格式。

# 日志级别

由低到高: ALL,TRACE, DEBUG, INFO, WARN, ERROR,FATAL,OFF ;

只会打印指定级别及以上级别的日志,SpringBoot 的默认级别是 INFO (这就意味着,INFO 之上级别是无法输出的),这个可以通 logging.level.root 来修改,root 指的是所有类,如果需要指定个别的包下的类或者是个别类,可以通过 logging.level.包名/类名 来修改。

  • ALL:打印所有日志
  • TRACE:追踪框架详细流程日志,一般不使用
  • DEBUG:开发调试细节日志
  • INFO:关键、感兴趣信息日志
  • WARN:警告但不是错误的信息日志,比如:版本过时
  • ERROR:业务错误日志,比如出现各种异常
  • FATAL:致命错误日志,比如 jvm 系统崩溃
  • OFF:关闭所有日志记录

# 日志分组

将相关的 logger 分组在一起,统一配置,SpringBoot 也支持。

logging:
  group:
    component:  ### 组名
      - com.dfd.spring.demo.componentDEMO
    config:
      - com.dfd.spring.demo.config
  level:
    component: debug  ### 对不同的组进行级别配置
    config: info
1
2
3
4
5
6
7
8
9
## 提供一个properties格式的参考
logging.group.component=com.dfd.spring.demo.componentDEMO,com.dfd.spring.demo.config
logging.level.component=debug
1
2
3

SpringBoot 预定义的两个组

Name Loggers
web org.springframework.core.codec
org.springframework.http
org.springframework.web
org.springframework.boot.actuate.endpoint.web
org.springframework.boot.web.servlet.ServletContextInitializerBeans
sql org.springframework.jdbc.core
org.hibernate.SQL
org.jooq.tools.LoggerListener

# 文件输出

SpringBoot 默认只把日志写在控制台,如果想额外记录到文件,可以在 application.yml 中添加 logging.file.name or logging.file.path 配置项。

logging.file.name logging.file.path 示例 效果
未指定 未指定 仅控制台输出
指定 未指定 my.log 写入指定文件。可以加路径
未指定 指定 /var/log 写入指定目录,文件名为 spring.log
指定 指定 以 logging.file.name 为准

# 文件归档与滚动切割

归档:每天的日志单独存到一个文档中。

切割:每个文件 10MB,超过大小切割成另外一个文件。

  1. 每天的日志应该独立分割出来存档。如果使用 logback(SpringBoot 默认整合),可以通过 application.properties/yaml 文件指定日志滚动规则。
  2. 如果是其他日志系统,需要自行配置(添加 log4j2.xml 或 log4j2-spring.xml)。
  3. 支持的滚动规则设置如下。
配置项 描述
logging.logback.rollingpolicy.file-name-pattern 日志存档的文件名格式(默认值:${LOG_FILE}.% d {yyyy-MM-dd}.% i.gz)
logging.logback.rollingpolicy.clean-history-on-start 应用启动时是否清除以前存档(默认值:false)
logging.logback.rollingpolicy.max-file-size 存档前,每个日志文件的最大大小(默认值:10MB)
logging.logback.rollingpolicy.total-size-cap 日志文件被删除之前,可以容纳的最大大小(默认值:0B)。设置 1GB 则磁盘存储超过 1GB 日志后就会删除旧日志文件
logging.logback.rollingpolicy.max-history 日志文件保存的最大天数 (默认值:7)

# 自定义配置

通常我们配置 application.properties 就够了。当然也可以自定义。比如:

日志系统 自定义
Logback logback-spring.xml、logback-spring.groovy、logback.xml、logback.groovy
Log4j2 log4j2-spring.xml、log4j2.xml
JDK (Java Util Logging) logging.properties

如果是 SpringBoot 环境下,请使用 -spring 变量(例如, logback-spring.xml 而不是 logback.xml )。具体原因如下:

点击查看

在Spring Boot中,使用logback-spring.xml而不是logback.xml作为Logback配置文件有几个重要原因和区别:

  1. 加载时机:
    • logback.xml:在应用程序上下文加载之前由Logback框架直接加载。
    • logback-spring.xml:由Spring Boot加载,在Spring环境和上下文创建之后进行处理。
  2. Spring Boot特性支持:
    • logback.xml:不支持Spring Boot的配置特性。
    • logback-spring.xml:可以使用Spring Boot的特性,如配置文件占位符和Profile-specific配置。
  3. 自定义启动行为:
    • logback-spring.xml允许你自定义Spring Boot的日志启动行为。
  4. 条件处理:
    • logback-spring.xml支持使用Spring Boot的@Profile注解来根据不同的环境进行条件配置。
  5. 扩展性:
    • logback-spring.xml提供了更好的扩展性,可以与Spring Boot的其他配置更好地集成。
  6. 错误处理:
    • 使用logback-spring.xml,如果配置有误,Spring Boot可以提供更友好的错误信息。

# 切换日志组合

<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>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

log4j2 支持 yaml 和 json 格式的配置文件

格式 依赖 文件名
YAML com.fasterxml.jackson.core:jackson-databind + com.fasterxml.jackson.dataformat:jackson-dataformat-yaml log4j2.yaml + log4j2.yml
JSON com.fasterxml.jackson.core:jackson-databind log4j2.json + log4j2.jsn

# 最佳实战

  1. 导入任何第三方框架,先排除它的日志包,因为 Boot 底层控制好了日志。
  2. 修改 application.properties 配置文件,就可以调整日志的所有行为。如果不够,可以编写日志框架自己的配置文件放在类路径下就行,比如 logback-spring.xml , log4j2-spring.xml 。
  3. 如需对接专业日志系统,也只需要把 logback 记录的日志灌倒 kafka 之类的中间件,这和 SpringBoot 没关系,都是日志框架自己的配置,修改配置文件即可。
#SpringBoot
上次更新: 2025/04/12, 05:37:39
Pull Requests
SpringBoot3-Web开发

← Pull Requests SpringBoot3-Web开发→

最近更新
01
Reactor 核心
02-24
02
前置条件
10-30
03
计算机网络
09-13
更多文章>
Theme by Vdoing | Copyright © 2019-2025 powered by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式