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

SpringBoot3快速入门笔记

springboot3简介

SpringBoot 帮我们简单、快速地创建一个独立的、生产级别的 Spring 应用(说明:SpringBoot底层是Spring)

大多数 SpringBoot 应用只需要编写少量配置即可快速整合 Spring 平台以及第三方技术

特性:

● 快速创建独立 Spring 应用

                ○ SSM:导包、写配置、启动运行

● 直接嵌入Tomcat、Jetty or Undertow(无需部署 war 包)【Servlet容器】

                ○ linux  java tomcat mysql: war 放到 tomcat 的 webapps下

                ○ jar: java环境;  java -jar

● 重点:提供可选的starter,简化应用整合

                ○ 场景启动器(starter):web、json、邮件、oss(对象存储)、异步、定时任务、缓存...

                ○ 导包一堆,控制好版本。

                ○ 为每一种场景准备了一个依赖; web-starter(只需要导入这一个,所有有关web的依赖都会导入且会控制好版本)。mybatis-starter

重点:按需自动配置 Spring 以及 第三方库

                ○ 如果这些场景我要使用(生效)。这个场景的所有配置都会自动配置好。

                ○ 约定大于配置:每个场景都有很多默认配置。

                ○ 自定义:配置文件中修改几项就可以

● 提供生产级特性:如 监控指标、健康检查、外部化配置等

               ○ 监控指标、健康检查(k8s)、外部化配置

● 无代码生成、无xml

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

快速入门

 * 步骤:

 * ①创建maven项目,在pom.xml中导入依赖

 *         1 所有springboot项目都必须继承自 spring-boot-starter-parent

 *           <parent>

 *             <groupId>org.springframework.boot</groupId>

 *             <artifactId>spring-boot-starter-parent</artifactId>

 *             <version>3.0.5</version>

 *          </parent>

 *         2 导入web开发的场景启动器

 *             <dependency>

 *                  <groupId>org.springframework.boot</groupId>

 *                  <artifactId>spring-boot-starter-web</artifactId>

 *             </dependency>

 *  ②创建启动SpringBoot项目的主入口程序

 *        随便是那个类都可以,在该类上添加@SpringBootApplication注解,代表这是一个SpringBoot应用程序

 *        在方法中通过SpringApplication调用静态方法run(当前类.class,args)

 *  ③正常创建三层架构 

代码举例

Pom.xml文件

​
<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> <!-- 所有springboot项目都必须继承自 spring-boot-starter-parent --> <parent><groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.0.5</version></parent> <groupId>com.atguigu</groupId> <artifactId>boot3-01-demo</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging><dependencies><!-- web开发的场景启动器 --> <dependency><groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency></dependencies><!--    SpringBoot应用打包插件--><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>​

<!--

mvn clean package把项目打成可执行的jar

java -jar demo.jar启动项目

-->

启动类:

@SpringBootApplication

public class Main {

    public static void main(String[] args) {

        SpringApplication.run(Main.class,args);

    }

}

注意

springboot的打包插件:

  <!--    SpringBoot应用打包插件-->

  <build>

    <plugins>

      <plugin>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-maven-plugin</artifactId>

        <version>${project.parent.version}</version> <!-- 与父模块一致 -->

      </plugin>

    </plugins>

  </build>

target目录下可以找到两个jar包,在文件路径下打开它,在改文件路径下打开终端窗口输入java -jar 文件名(回车);即可运行该项目

依赖管理机制

补充:

● 官方提供的场景:命名为:spring-boot-starter-*(官方默认提供了许多场景)

● 第三方提供场景:命名为:*-spring-boot-starter

starter(spring-boot-starter-web--->也叫web场景启动器)的starter(spring-boot-starter)

1、为什么导入starter-web所有相关依赖都导入进来?

(只要导入一个场景启动器,这个场景启动器会自动吧它用到的所有功能的以及相关的依赖导入)

      ● 开发什么场景,导入什么场景启动器。

      ● maven依赖传递原则。A-B-C: A就拥有B和C

      导入 场景启动器。 场景启动器 自动把这个场景的所有核心依赖全部导入进来

2、为什么版本号都不用写?

      每个boot项目都有一个父项目spring-boot-starter-parent

      ● parent的父项目是spring-boot-dependencies

      父项目 (spring-boot-dependencies)版本仲裁中心,把所有常见的jar的依赖版本都声明好了。

      ● 比如:mysql-connector-j

3、自定义版本号

      利用maven的就近原则

           ○ 直接在当前项目properties标签中声明父项目用的版本属性的key

           ○ 直接在导入依赖的时候声明版本

4   第三方的jar包

● boot父项目没有管理的需要自行声明好版本号

 自动配置机制

初步理解

● 自动配置的 Tomcat、SpringMVC 等

  ○ 导入场景,容器中就会自动配置好这些场景的核心组件。

代码测试:

@SpringBootApplication

public class Boot302DemoApplication {

    public static void main(String[] args) {

        //java10:局部变量类型的自动推断

        var ioc = SpringApplication.run(Boot302DemoApplication.class, args);

        //1 获取ioc容器中所有组件的名字------->SpringBoot把以前配置的核心组件都给我们配置好了。

        String[] names = ioc.getBeanDefinitionNames();

        for (String name:names) {

            System.out.println("name = " + name);

        }

    }

}

● 默认的包扫描规则

  ○ @SpringBootApplication 标注的类就是主程序类

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

  ○ 自定义扫描路径

    方式1 @SpringBootApplication(scanBasePackages = "com.atguigu")-----------用属性

    方式2 @ComponentScan("com.atguigu") 直接指定扫描的路径

本质: @SpringBootApplication=@ComponentScan+@SpringBootConfiguration+@EnableAutoConfiguration

● 配置默认值

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

  ○ 绑定了配置文件中每一项值的类: 属性类。

  ○ 比如:

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

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

● 按需加载自动配置

  ○ 导入场景spring-boot-starter-web

  ○ 场景启动器除了会导入相关功能依赖,导入一个spring-boot-starter是所有starter的starter,基础核心starter

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

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

    导入哪个场景就开启哪个自动配置

总结: 导入场景启动器、触发 spring-boot-autoconfigure这个包的自动配置生效、容器中就会具有相关场景的功能

常用注解

组件注解

@Configuration //说明这是一个配置类

@SpringBootConfiguration //代表此类是一个Springboot的配置类

@Bean、//替代bean标签

@Scope、//组件默认是单实例的,可以通过此注解设置单个还是多个

@Controller、 @Service、@Repository、@Component

@Import、//导入第三方组件到ioc容器(给容器中方指定类型的组件,组件的名字默认是全类名)

@ComponentScan

组件注册步骤:

1、@Configuration 编写一个配置类

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

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

条件注解 

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

@ConditionalOnXxx

@ConditionalOnClass(name="类的权限定符"):如果类路径中存在这个类,则触发指定行为

@ConditionalOnMissingClass:如果类路径中不存在这个类,则触发指定行为

@ConditionalOnBean:如果容器中存在这个Bean(组件),则触发指定行为

@ConditionalOnBean(value=组件类型,name=组件名字):判断容器中是否有这个类型的组件,并且名字是指定的值

@ConditionalOnMissingBean:如果容器中不存在这个Bean(组件),则触发指定行为

注意:这些注解还可以用在类上;

放在类级别:如果注解判断生效整个配置配才生效;

放在方法级别:只是单独对这个方法判断;

场景:

● 如果存在FastsqlException这个类,给容器中放一个Cat组件,名cat01,

● 否则,就给容器中放一个Dog组件,名dog01

● 如果系统中有dog01这个组件,就给容器中放一个 User组件,名zhangsan

● 否则,就放一个User,名叫lisi

测试代码:

@SpringBootConfigurationpublic class AppConfig {@ConditionalOnClass(name="com.alibaba.druid.FastsqlException")@Beanpublic Cat cat01(){return new Cat();//组件名就是方法名}@ConditionalOnMissingClass(value="com.alibaba.druid.FastsqlException")@Beanpublic Dog dog01(){return new Dog();}@ConditionalOnBean(value= Dog.class)@Beanpublic User user1(){User user = new User();user.setUserName("zhangsan");return user;}@ConditionalOnMissingBean(value= Dog.class)@Beanpublic User user2(){User user = new User();user.setUserName("lisi");return user;}}

属性绑定

@ConfigurationProperties: 声明组件的属性和配置文件哪些前缀开始项进行绑定(名字要一致)(既能表在类上也能标在方法上,用了此注解,组件一定要加入到ioc容器)

@EnableConfigurationProperties:快速注册注解

常用于导入第三方组件进行属性绑定,springboot默认只扫描自己主程序所在的包,所以别人写好的类使用@Component与@ConfigurationProperties(prefix = "…")配置好了组件,我们也无法扫描到,所以只能使用@EnableConfigurationProperties配置属性值并将起放入到ioc容器中

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

步骤:

        ● 1、给容器中注册组件(@Component、@Bean)----------------组件只有在容器中才有这些功能

        ● 2、使用@ConfigurationProperties 声明组件和配置文件的哪些配置项进行绑定

@ConfigurationProperties+@Component代码举例:

文件:

pig.id=1

pig.name=佩奇

pig.age=5

要放入ioc的组件的类

@Component

@ConfigurationProperties(prefix = "pig")

/*

注意:配置文件的的名字只要与类中的属性名一一对应就可以赋值

 */

@Data

public class Pig {

    private Long id;

    private String name;

    private Integer age;

}

@EnableConfigurationProperties代码举例

配置文件:

sheep.id=2

sheep.name=苏西

sheep.age=4

实体类

@Data

@ConfigurationProperties(prefix = "sheep")//没有搭配@Component了因为在配置类上开启了开启组件的属性绑定

public class Sheep {

    private Long id;

    private String name;

    private Integer age;

}

在配置类上加:

@EnableConfigurationProperties(Sheep.class)

/**

 * 1 开启组件的属性绑定

 * 2 默认会将组件放入到ioc容器中

 * 注意:还是要使用@ConfigurationProperties(prefix = "sheep")指明前缀

 */

深入了解自动配置原理

springboot完整流程

①springboot怎么实现导入一个starter,写一些简单配置,应用就能跑起来,我们无需关心整合

②为什么tomcat的端口号可以配置在appliction.properties中,并且Tomcat能启动成功

③导入场景后那些自动配置能生效

1、导入starter-web:导入了web开发场景

            ● 1、场景启动器导入了相关场景的所有依赖:starter-json、starter-tomcat、springmvc

            ● 2、每个场景启动器都引入了一个spring-boot-starter,核心场景启动器。

            ● 3、核心场景启动器引入了spring-boot-autoconfigure包。

            ● 4、spring-boot-autoconfigure里面囊括了所有场景的所有配置。(所以导入的所有依赖都不需要写版本)--所有场景要用的组件在配置类里都写好了,这些配置类就在spring-boot-autoconfigure包中。

            ● 5、只要这个包下的所有类都能生效,那么相当于SpringBoot官方写好的整合功能就生效了。

            ● 6、SpringBoot默认却扫描不到 spring-boot-autoconfigure下写好的所有配置类。(这些配置类给我们做了整合操作),默认只扫描主程序所在的包。

2、主程序:@SpringBootApplication

                    ● 1、@SpringBootApplication由三个注解组成@SpringBootConfiguration、@EnableAutoConfiguratio、            @ComponentScan

                    ● 2、SpringBoot默认只能扫描自己主程序所在的包及其下面的子包,扫描不到 spring-boot-autoconfigure包中官方写好的配置类

                    ● 3、@EnableAutoConfiguration:SpringBoot 开启自动配置的核心。

                                   ○ 1. 是由@Import(AutoConfigurationImportSelector.class)提供功能:批量给容器中导入组件。

                                   ○ 2. SpringBoot启动会默认加载 142个配置类。

                                   ○ 3. 这142个配置类来自于spring-boot-autoconfigure下 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件指定的

                                   ○ 项目启动的时候利用 @Import 批量导入组件机制把 autoconfigure 包下的142 xxxxAutoConfiguration类导入进来(自动配置类)

                                  ○ 虽然导入了142个自动配置类

                   ● 4、按需生效:

                                 ○ 并不是这142个自动配置类都能生效

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

3、xxxxAutoConfiguration自动配置类

                 ● 1、给容器中使用@Bean 放一堆组件。

                 ● 2、每个自动配置类都可能有这个注解@EnableConfigurationProperties(ServerProperties.class),用来把配置文件中配的指定前缀的属性值封装到 xxxProperties属性类中

                 ● 3、以Tomcat为例:把服务器的所有配置都是以server开头的。配置都封装到了属性类中

                 ● 4、给容器中放的所有组件的一些核心参数,都来自于xxxProperties。xxxProperties都是和配置文件绑定。

                 ● 5、只需要改配置文件的值,核心组件的底层参数都能修改

4、写业务,全程无需关心各种整合(底层这些整合写好了,而且也生效了)

1、导入starter,就会导入autoconfigure包。

2、autoconfigure 包里面 有一个文件 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports,里面指定的所有启动要加载的自动配置类

3、@EnableAutoConfiguration 会自动的把上面文件里面写的所有自动配置类都导入进来(通过@Import批量导入)xxxAutoConfiguration(配置类) 是有条件注解进行按需加载

4、xxxAutoConfiguration给容器中导入一堆组件,组件都是从 xxxProperties(属性类,它绑定了配置文件,所以只要修改配置文件就可以修改组件参数)中提取属性值

5、xxxProperties又是和配置文件进行了绑定

效果:导入starter、修改配置文件,就能修改底层行为。

yaml文件语法

痛点:SpringBoot 集中化管理配置,application.properties

问题:配置多以后难阅读和修改,层级结构辨识度不高

YAML 是 "YAML Ain't a Markup Language"(YAML 不是一种标记语言)。在开发的这种语言时,YAML 的意思其实是:"Yet Another Markup Language"(是另一种标记语言)。

                          ● 设计目标,就是方便人类读写

                          ● 层次分明,更适合做配置文件

                          ● 使用.yaml .yml作为文件后缀

1. 基本语法

          ● 大小写敏感

          ● 使用缩进表示层级关系k: v使用冒号+空格分割k,v

          ● 缩进时不允许使用Tab键,只允许使用空格。换行

          ● 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可

          ● # 表示注释,从这个字符一直到行尾,都会被解析器忽略。

细节

● birthDay 推荐写为 birth-day

● 文本:\n在单引号内不生效,在双引号内生效)

  ○ 单引号不会转义【\n 则为普通字符串显示】

  ○ 双引号会转义【\n会显示为换行符】

例如:name:'zhangsan \n 123'---->打印:name=zhangsan \n 123

          name:"张三 \n 457"----》打印:name=张三(换行) 123

● 大文本

  ○ |开头,大文本写在下层,保留文本格式,换行符正确显示

  ○ >开头,大文本写在下层,折叠换行符(若没有缩进会压缩换行,即将换行变为空格;若有缩进则保留原文本格式)

例如:

    text:

      - abc

      - gii

      - |

        dogs:

          - dogName: xiaohei

            dogAge: 1

          - dogName: xiaohuang

            dogAge: 1

      - >

        cghdsku

        gsdvkj

        ghusduvch

打印:

● 多文档合并

  ○ 使用---可以把多个yaml文档合并在一个文档中,每个文档区依然认为内容独立

支持的写法:

         ● 对象:键值对的集合,如:映射(map)/ 哈希(hash) / 字典(dictionary)

         ● 数组:一组按次序排列的值,如:序列(sequence) / 列表(list)

         ● 纯量:单个的、不可再分的值,如:字符串、数字、bool、日期

.properties测试代码:

@Component@ConfigurationProperties(prefix = "person")//和配置文件person前缀的所有配置进行绑定@Data@NoArgsConstructor//自动生成一个无参构造器@AllArgsConstructor//自动生成一个全参构造器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}

child类

@Data

public class Child {

    private String name;

    private Integer age;

    private Date birthDay;

    private List<String> text;

}

dog类

@Data

public class Dog {

    private String dogName;

    private int dogAge;

}

cat类

@Data

public class Cat {

    private String catName;

    private int catAge;

}

Applicationl.properties文件

#properties表示复杂对象

person.name=张三

person.age=30

person.birthDay=1996/10/12 12:12:12

person.like=true

person.child.name=李四

person.child.age=12

person.child.brithDay=2013/12/12

person.child.text[0]=abc

person.child.text[1]=gcs

person.dogs[0].dogName=小黄

person.dogs[0].dogAge=1

person.dogs[1].dogName=小黑

person.dogs[1].dogAge=1

person.cats.c1.catName=小暖

person.cats.c1.catAge=1

person.cats.c2.catName=小白

person.cats.c2.catAge=1

#子对象用嵌套;数组用[];Map用.

.yaml测试代码:

person:

  name: zhangsan

  age: 30

  birthDay: 1996/12/10

  like: true

  child:

    name: lisi

    age: 12

    birthDay: 2013/2/23

  # text: ["abc","gdk"] 

    text:

      - abc

      - gii

  dogs:

    - dogName: xiaohei

      dogAge: 1

    - dogName: xiaohuang

      dogAge: 1

  cats:

    c1:

      catName: xiaonuan

      catAge: 1

    c2: {catName: xiaobai,catAge: 2}

      #对象也可以用{}表示

日志

整合原理

简介:

1. Spring使用commons-logging作为内部日志,但底层日志实现是开放的。可对接其他日志框架。

  a. spring5及以后 commons-logging被spring直接自己写了。

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

3. logback是默认使用的。

4. 虽然日志框架很多,但是我们不用担心,使用 SpringBoot 的默认配置就能工作的很好。

SpringBoot怎么把日志默认配置好的

1、每个starter场景,都会导入一个核心场景spring-boot-starter

2、核心场景引入了日志的所用功能spring-boot-starter-logging

3、默认使用了logback + slf4j 组合作为默认底层日志

4、日志是系统一启动就要用,xxxAutoConfiguration是系统启动好了以后放好的组件,后来用的。

5、日志是利用监听器机制配置好的。ApplicationListener。

6、日志所有的配置都可以通过修改配置文件实现。以logging开始的所有配置。

日志格式与记录日志

默认输出格式:

● 时间和日期:毫秒级精度

日志级别:ERROR, WARN, INFO, DEBUG, or TRACE.

● 进程 ID

● ---: 消息分割符

● 线程名: 使用[]包含

● Logger 名: 通常是产生日志的类名

消息: 日志记录的内容

注意: logback 没有FATAL级别,对应的是ERROR

记录日志:

Logger logger = LoggerFactory.getLogger(getClass());------------logger.info("要记录的内容")

或者使用Lombok的@Slf4j注解----------------log.info("要记录的内容")

例如:

@Slf4j

@RestController

public class HelloController {

    Logger logger = LoggerFactory.getLogger(getClass());

    @GetMapping("/h")

    public String hello(){

        /**

         * 实现:方法一进来就打印日志

         * 方法一:通过LoggerFactory调用getLogger(getClass())传入当前类-----得到一个 Logger对象logger,

         *                   通过对象logger调用info就可以记录想要的东西了

         * 方法二:注解@Slf4j中有一个log

         *                   通过log调用info也可以传入属性

         */

        logger.info("哈哈哈,方法进来了1");

        log.info("哈哈哈,方法进来了2");

        return "hello";

    }

}

日志级别

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

  ○ 只会打印指定级别及以上级别的日志

  ○ ALL:打印所有日志

  ○ TRACE:追踪框架详细流程日志,一般不使用

  ○ DEBUG:开发调试细节日志

  ○ INFO:关键、感兴趣信息日志

  ○ WARN:警告但不是错误的信息日志,比如:版本过时

  ○ ERROR:业务错误日志,比如出现各种异常

  ○ FATAL:致命错误日志,比如jvm系统崩溃(logback 没有FATAL级别,对应的是ERROR

  ○ OFF:关闭所有日志记录

● 不指定级别的所有类,都使用root指定的级别作为默认级别

● SpringBoot日志默认级别是 INFO

1. application.properties/yaml中配置logging.level.<logger-name>=<level>指定日志级别(我们可以精确的调节某一个类的日志级别后某一个包下的日志级别)

2. level可取值范围:TRACE, DEBUG, INFO, WARN, ERROR, FATAL, or OFF,定义在 LogLevel类中

3. root 的logger-name叫root,可以配置logging.level.root=warn,代表所有未指定日志级别都使用 root 的 warn 级别

代码举例:

@Slf4j

@RestController

public class HelloController {

    Logger logger = LoggerFactory.getLogger(getClass());

    @GetMapping("/h")

    public String hello(String a,String b){

        log.trace("trac 日志....");

        log.debug("debug 日志....");

        log.info("info 日志....");

        log.warn("warn 日志....,参数a:{} b:{}",a,b);

        log.error("error 日志....");

        /**

         * 只打印了info,warn,error日志

         * springboot底层默认的日志级别是info(只会打印info及以后级别的日志)

         */

        return "hello";

    }

}

Applicaton.properties文件

#默认所有日志没有精确指定级别就使用root的默认级别(info)

#将默认级别调整为debug级别

logging.level.root=debug

#将controller包下的日志级别调整为warn级别

logging.level.com.atgiugu.logging1.controller=warn

日志分组

将相关的logger分组在一起,统一配置。SpringBoot 也支持。比如:Tomcat 相关的日志统一设置

例如:

#日志分组

#调整某个包下的日志级别

#logging.level.com.atgiugu.logging1.controller=debug

#logging.level.com.atgiugu.logging1.service=debug

#logging.level.com.aaa=debug

#logging.level.com.bbb=debug

logging.group.abc=com.atgiugu.logging1.controller,com.atgiugu.logging1.service,com.aaa,com.bbb

logging.level.abc=debug

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.properties中添加logging.file.name or logging.file.path配置项。

例如:

Application.properties文件

#指定日志文件的路径(只给了一个地址的话,会在指定路径下生成一个默认名字的文件)

#logging.file.path=

#指定日志文件的名

#logging.file.name=

#日志文件的名与路径都不配,那么默认配置文件只在控制台输出

#logging.file.name

#1 只写名字,就生成到当前项目同位置的demo.log

#logging.file.name=demo.log

#2 名字+路径,就生成到指定位置的指定文件

logging.file.name=C://demo.log

#注意:如果logging.file.path=与logging.file.name=同时存在,那么以logging.file.name优先

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文件:

#归档与切割

logging.logback.rollingpolicy.file-name-pattern=${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz

#${LOG_FILE}就是前面配置的文件名;%d{yyyy-MM-dd}格式化一个日期,是年月日;%i是当天的第几个文件;gz是压缩包格式

#只要文件攒够1MB就切割为一个单独文件

logging.logback.rollingpolicy.max-file-size=1MB

 

自定义日志系统

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

日志系统        

自定义

Logback        

logback-spring.xml, logback-spring.groovy, logback.xml, or logback.groovy

Log4j2

        log4j2-spring.xml or log4j2.xml

JDK (Java Util Logging)        

logging.properties

自定以文件后,就按照自定义文件的规则来输出日志

如果可能,我们建议您在日志配置中使用-spring 变量(例如,logback-spring.xml 而不是logback.xml)。如果您使用标准配置文件,spring 无法完全控制日志初始化。

切换日志组合

利用maven的就近原则

步骤:①在spring-boot-starter中排除logback依赖(spring-boot-starter-logging)

          ②导入log4j2的依赖(spring-boot-starter-log4j2)

<dependency>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-web</artifactId>

</dependency>

<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>

导第三方日志如果它依赖了一个日志(jul),排除掉这个框架的默认日志

总结:

1. 导入任何第三方框架,先排除它的日志包,因为Boot底层控制好了日志

2. 修改 application.properties 配置文件,就可以调整日志的所有行为。如果不够,可以编写日志框架自己的配置文件放在类路径下就行,比如logback-spring.xml,log4j2-spring.xml

3. 业务中使用slf4j-api记录日志。不要再 sout 了

相关文章:

SpringBoot3快速入门笔记

springboot3简介 SpringBoot 帮我们简单、快速地创建一个独立的、生产级别的 Spring 应用&#xff08;说明&#xff1a;SpringBoot底层是Spring&#xff09; 大多数 SpringBoot 应用只需要编写少量配置即可快速整合 Spring 平台以及第三方技术 特性&#xff1a; ● 快速创建…...

vue3中,element-plus中el-input的v-model和value的用法示例

el-input的v-model&#xff0c;邦定响应式变量 <el-col :span"6"><el-form-item label"检验类别" prop"verifyType"><el-input v-model"applyAllInfo.applyBasicInfo.verifyTypeName" readonly /></el-form-item…...

python求π近似值

【问题描述】用公式π/4≈1-1/31/5-1/7..1/(2*N-1).求圆周率PI的近似值。 从键盘输入一个整数N值&#xff0c;利用上述公式计算出π的近似值&#xff0c;然后输出π值&#xff0c;保留小数后8位。 【样例输入】1000 【样例输出】3.14059265 def countpi(N):p0040nowid0for i i…...

Gerapy二次开发:搜索器组件设计开发与应用(Vue父子组件通信)

搜索器组件设计开发与应用 写在前面搜索器字段定义与样式设计具体实现components/Search.vuedeploy/Index.vue后端views.py运行效果总结欢迎加入Gerapy二次开发教程专栏! 本专栏专为新手开发者精心策划了一系列内容,旨在引领你深入探索Gerapy框架的二次迭代之旅。 本专栏将全…...

深入解析Python爬虫技术:从基础到实战的功能工具开发指南

一、引言:Python 爬虫技术的核心价值 在数据驱动的时代,网络爬虫作为获取公开数据的重要工具,正发挥着越来越关键的作用。Python 凭借其简洁的语法、丰富的生态工具以及强大的扩展性,成为爬虫开发的首选语言。根据 Stack Overflow 2024 年开发者调查,68% 的专业爬虫开发者…...

Python爬虫-爬取全球股市涨跌幅和涨跌额数据

前言 本文是该专栏的第52篇,后面会持续分享python爬虫干货知识,记得关注。 本文中,笔者将基于Python爬虫,实现批量采集全球股市行情(亚洲,美洲,欧非,其他等)的各股市“涨跌幅”以及“涨跌额”数据。 具体实现思路和详细逻辑,笔者将在正文结合完整代码进行详细介绍。…...

【NLP 59、大模型应用 —— BPE 算法】

你和生生不息的河流&#xff0c;生动了我人生中的美好瞬间 —— 25.4.11 一、词表的构造问题 为了nlp模型训练&#xff0c;词表&#xff08;字表&#xff09;是必要的 统计训练语料中的所有字符&#xff08;或词&#xff09;是一种做法&#xff0c;但是容易出现一些问题&…...

SQL基础入门:从CRUD到JOIN再到索引(通俗易懂版)

一、为什么需要SQL&#xff1f; 想象你在管理一个图书馆&#xff1a; 传统方法&#xff1a;手动记录每本书的位置、借阅者、归还日期SQL方法&#xff1a;用数据库系统自动管理&#xff0c;快速查询《Java编程思想》在哪个书架 SQL&#xff08;Structured Query Language&…...

系统编程1(进程的概念与原理)

进程的概念与原理 计算机组成部分一般遵循冯诺依曼结构&#xff0c;也就是由控制器、运算器、存储器、输入设备、输出设备五个部分组成。 ⦁ 程序的编译 一般在编写出程序之后&#xff0c;并不能直接运行&#xff0c;而是需要把程序通过编译器进行编译&#xff0c;生成可执行…...

Git基础知识

Git基础知识 目录 一、Git简介 1.1 什么是Git&#xff1f;1.2 基本概念1.3 Git与其他版本控制系统的区别 二、Git安装与配置 2.1 安装Git2.2 基础配置2.3 高级配置2.4 多账户配置 三、基本操作 3.1 创建仓库3.2 基本工作流3.3 分支操作3.4 查看历史 四、高级操作 4.1 撤销修改…...

【Flink运行时架构】核心组件

在Flink的运行架构中&#xff0c;有两大比较重要的组件&#xff1a;作业管理器&#xff08;JobManager&#xff09;和任务管理器&#xff08;TaskManager&#xff09;。 Flink的作业提交与任务处理时的系统如下图所示。 其中&#xff0c;客户端并不是处理系统的一部分&#xff…...

【区块链安全 | 第四十篇】合约审计之delegatecall(二)

文章目录 漏洞代码代码分析攻击流程攻击代码前文重现修复建议审计思路 在阅读本文之前&#xff0c;请确保已先行阅读&#xff1a;【区块链安全 | 第三十九篇】合约审计之delegatecall&#xff08;一&#xff09; 漏洞代码 存在一漏洞代码如下&#xff1a; // 库合约&#xf…...

Redis实现分布式定时任务

设计思路 任务表示&#xff1a;每个任务通过一个特定格式的键来表示。键名可以包含任务ID等信息&#xff0c;值可以是任务的具体内容或指向任务详情的引用。过期机制&#xff1a;利用Redis的EXPIRE命令为任务设置过期时间&#xff0c;当到达设定的时间点时&#xff0c;Redis会…...

ERC20合约的基本调用

文章目录 ERC20合约的基本调用合约功能compile.js 代码读取文件 进行合约编译获取二进制对象导出对象 index.js 代码编译合约读取私钥设置收款账户构造 web3 对象获取账户地址获取 abi 和 bin创建合约交易部署合约构造转账交易验证转账后余额 测试项目目录执行查询 ERC20合约的…...

『Kubernetes(K8S) 入门进阶实战』实战入门 - Pod 详解

『Kubernetes(K8S) 入门进阶实战』实战入门 - Pod 详解 Pod 结构 每个 Pod 中都可以包含一个或者多个容器&#xff0c;这些容器可以分为两类 用户程序所在的容器&#xff0c;数量可多可少Pause 容器&#xff0c;这是每个 Pod 都会有的一个根容器&#xff0c;它的作用有两个 可…...

【React框架】什么是 Vite?如何使用vite自动生成react的目录?

什么是 Vite&#xff1f; Vite 是一个基于原生 ES Modules 开发的前端构建工具&#xff0c;由 Evan You&#xff08;Vue 的作者&#xff09;开发。它最大的特点包括&#xff1a; 极速冷启动&#xff1a;因为利用了浏览器原生的 ES Modules&#xff0c;所以在开发时无需等待整…...

JS实现文件点击或者拖拽上传

B站看到了渡一大师课的切片&#xff0c;自己实现了一下&#xff0c;做下记录 效果展示 分为上传前、上传中和上传后 实现 分为两步 界面交互网络请求 源码如下 upload.html <!DOCTYPE html> <html lang"zh-CN"><head><meta charset&q…...

【Vue #3】指令补充样式绑定

一、指令修饰符 Vue 的指令修饰符&#xff08;Directive Modifiers&#xff09;是 Vue 模板语法中的重要特性&#xff0c;它们以半角句号 . 开头&#xff0c;用于对指令的绑定行为进行特殊处理 修饰符作用如下&#xff1a; 简化事件处理&#xff08;如阻止默认行为、停止冒泡…...

Vue.js组件安全工程化演进:从防御体系构建到安全性能融合

——百万级流量场景下的安全组件架构与源码级解决方案 文章目录 总起&#xff1a;安全工程化的组件革命 分论&#xff1a; 一、现存组件架构的七宗罪与安全改造路径   1.1 组件生态安全赤字现状   1.2 架构级安全缺陷深度剖析   1.3 性能与安全的死亡螺旋 二、百万级…...

LINUX基础 [二] - Linux常见指令

目录 &#x1f4bb;前言 &#x1f4bb;指令 &#x1f3ae;ls指令 &#x1f3ae;pwd指令 &#x1f3ae;whoami指令 &#x1f3ae;cd指令 &#x1f3ae;clear指令 &#x1f3ae;touch指令 &#x1f3ae;mkdir指令 &#x1f3ae;rmdir指令 &#x1f3ae;rm指令 &#…...

Linux进阶命令

目录 一、touch 1. 基本语法 2. 常用选项 二、which 1. 基本语法 2. 主要功能 3. 常用选项 三、find 1. 基本语法 2. 常用选项和表达式 四、more 1. 基本语法 2. 常用操作 3. 对比 more 和 less 五、grep 1. 基本语法 2. 常用选项 六、wc 1. 基本语法 2. 常…...

【Spring Boot 过滤器】

文章目录 前言一、什么是过滤器 Filter&#xff1f;二、Spring Boot 中使用 Filter 的方式1. 使用 Component 注解2. 使用 FilterRegistrationBean 显式注册 三、自定义过滤器示例1. 引入必要依赖2. 创建一个自定义 Filter3. 使用 FilterRegistrationBean 显式注册 四、多个 Fi…...

SPI通讯的软硬件NSS SSM SSI

学习自记&#xff1a; 1. NSS&#xff08;Slave Select&#xff0c;从设备选择&#xff09;​​ ​​功能​​&#xff1a; NSS是SPI通信中用于选择从设备的信号线。主设备通过拉低NSS信号选中某个从设备&#xff0c;使其参与通信。通信结束后&#xff0c;主设备释放NSS&#…...

Java基础:集合List、Map、Set(超详细版)

集合体系概述 Collection常用方法 补充&#xff1a;addAll() Collection的遍历方式 迭代器 增强for&#xff08;空集合可以&#xff0c;null不可以&#xff09; lambda 集合对象存储对象原理 遍历方式的区别 List集合 特点、特有方法 遍历方式 &#xff08;同上&#xff09…...

vue+leaflet 区域划分_反向遮罩层

leaflet 区域划分_遮罩层 geojson在线生成器网址:(https://datav.aliyun.com/portal/school/atlas/area_selector) 点击前往阿里云geojson生成器 效果图: 实现下面效果,只需要把addSateLayer函数的调用取消掉就好了. //添加遮罩层代码function addMask() {var latlngs;var fe…...

聊一聊原子操作和弱内存序

1、原子操作概念 在并发编程中&#xff0c;原子操作&#xff08;Atomic Operation&#xff09;是实现线程安全的基础机制之一。从宏观上看&#xff0c;原子操作是“不可中断”的单元&#xff0c;但若深入微观层面&#xff0c;其本质是由底层处理器提供的一组特殊指令来保证其原…...

免费送源码:Java+ssm+MySQL 校园二手书销售平台设计与实现 计算机毕业设计原创定制

摘 要 信息化社会内需要与之针对性的信息获取途径&#xff0c;但是途径的扩展基本上为人们所努力的方向&#xff0c;由于站在的角度存在偏差&#xff0c;人们经常能够获得不同类型信息&#xff0c;这也是技术最为难以攻克的课题。针对校园二手书销售平台等问题&#xff0c;对校…...

DAPP实战篇:使用ethersjs连接智能合约并输入地址查询该地址余额

本系列目录 专栏:区块链入门到放弃查看目录-CSDN博客文章浏览阅读400次。为了方便查看将本专栏的所有内容列出目录,按照顺序查看即可。后续也会在此规划一下后续内容,因此如果遇到不能点击的,代表还没有更新。声明:文中所出观点大多数源于笔者多年开发经验所总结,如果你…...

14.【.NET 8 实战--孢子记账--从单体到微服务--转向微服务】--微服务基础工具与技术--CAP

CAP 是一款专为 .NET 生态设计的开源框架&#xff0c;其核心目标是解决微服务中跨服务数据一致性问题。在分布式系统中&#xff0c;传统事务无法跨服务保证数据一致性&#xff0c;CAP 通过本地事务与消息记录绑定&#xff0c;再利用消息中间件&#xff08;如 RabbitMQ、Kafka 等…...

智能资源管理机制-重传机制

一、发送端资源管理的核心机制 1. 滑动窗口&#xff08;Sliding Window&#xff09; 这是TCP协议的核心优化设计&#xff1a; 窗口动态滑动&#xff1a;发送端不需要保留所有已发送的分组&#xff0c;只需维护一个"发送窗口"窗口大小&#xff1a;由接收方通告的接…...

【Linux网络与网络编程】08.传输层协议 UDP

传输层协议负责将数据从发送端传输到接收端。 一、再谈端口号 端口号标识了一个主机上进行通信的不同的应用程序。在 TCP/IP 协议中&#xff0c;用 "源IP"&#xff0c;"源端口号"&#xff0c;"目的 IP"&#xff0c;"目的端口号"&…...

局域网下ESP32-S3 LED灯的UDP控制

在局域网下通过IP地址控制ESP32-S3上的LED&#xff0c;可以使用UDP或TCP协议。以下是一个基于UDP协议的完整示例&#xff0c;包括ESP32-S3的服务器代码和一个简单的Python客户端代码。 ESP32-S3 服务器代码 import socket import time import network import machineled Non…...

call、bind、apply

call、bind、apply它们三个都是函数的方法&#xff0c;都可以用于改变this的指向问题。 var person "liangxiao" let obj {name:"张三",say:function() {console.log(this.name);} }obj.say(); setTimeout(function() {obj.say(); },1000) obj.say()打…...

Redis 哨兵模式 搭建

1 . 哨兵模式拓扑 与 简介 本文介绍如何搭建 单主双从 多哨兵模式的搭建 哨兵有12个作用 。通过发送命令&#xff0c;让Redis服务器返回监控其运行状态&#xff0c;包括主服务器和从服务器。 当哨兵监测到master宕机&#xff0c;会自动将slave切换成master&#xff0c;然后通过…...

客户端负载均衡与服务器端负载均衡详解

客户端负载均衡与服务器端负载均衡详解 1. 客户端负载均衡&#xff08;Client-Side Load Balancing&#xff09; 核心概念 定义&#xff1a;负载均衡逻辑在客户端实现&#xff0c;客户端主动选择目标服务实例。典型场景&#xff1a;微服务内部调用&#xff08;如Spring Cloud…...

Ningx负载均衡

Ningx负载均衡 upstream(上游)配置负载均衡1、weight&#xff08;加权轮询&#xff09;2、ip_hash&#xff08;负载均衡&#xff09;3、url hash负载均衡4、least_conn&#xff08;最小连接负载均衡&#xff09; upstream(上游)配置负载均衡 Nginx负载均衡 参考: nginx从安装…...

头歌软件工程导论UML画图题(基于starUML)

一.结构化分析方法-数据流图 本关卡需要画图的一共有5关&#xff0c;直接将此图画好每关提交一次即可&#xff0c;以下的所有图均以此方法提交 二.面向对象分析之用例图 三.面向对象分析之类图 注意此处创建Class之后&#xff0c;双击Class出现以下选项 点击相应的选项创建属性…...

智能车摄像头开源—9 动态权、模糊PID、速度决策、路径优化

目录 一、前言 二、动态权 1.概述 2.偏差值加动态权 三、模糊PID 四、速度决策 1.曲率计算 2.速度拟合 3.速度控制 五、路径 六、国赛视频 一、前言 在前中期通过识别直道、弯道等元素可进行加减速操作实现速度的控制&#xff0c;可进一步缩减一圈的运行速度&#xff…...

java基础 this和super的介绍

this和super this关键字的用法super关键字的用法this与super的区别和注意事项 this关键字的用法 this是自身的一个对象&#xff0c;代表对象本身&#xff0c;可以理解为&#xff1a;指向对象本身的一个指针 class Person{private String name;private int age;public String …...

《Python星球日记》第25天:Pandas 数据分析

名人说&#xff1a;路漫漫其修远兮&#xff0c;吾将上下而求索。—— 屈原《离骚》 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 订阅专栏&#xff1a;《Python星球日记》 目录 一、引言二、数据分组与聚合1. 分组操…...

C++在Linux上生成动态库并调用接口测试

加减乘除demo代码 项目结构 CPP/ ├── calculator.cpp ├── calculator.h ├── main.cpp 头文件 #ifndef CALCULATOR_H #define CALCULATOR_H#ifdef __cplusplus extern "C" {#endifdouble add(double a, double b);double subtract(double a, double b…...

Cesium.js(6):Cesium相机系统

Camera表示观察场景的视角。通过操作摄像机&#xff0c;可以控制视图的位置、方向和角度。 帮助文档&#xff1a;Camera - Cesium Documentation 1 setView setView 方法允许你指定相机的目标位置和姿态。你可以通过 Cartesian3 对象来指定目标位置&#xff0c;并通过 orien…...

机器学习中的数学(PartⅡ)——线性代数:概述

首先引入代数和线性代数的概念&#xff1a; 在将一些直观的、基于经验或直觉的概念转化为严格的数学或逻辑定义时&#xff0c;一种常用方法是构建一组对象和一组操作这些对象的规则&#xff0c;这就是代数。线性代数是研究向量和某些操作向量的规则。 其次从更广泛的意义上定…...

基于双闭环PID控制器的永磁同步电机控制系统匝间故障Simulink仿真

欢迎微♥关注“电击小子程高兴的MATLAB小屋”获取巨额优惠 1.模型简介 本仿真模型基于MATLAB/Simulink&#xff08;版本MATLAB 2013Rb&#xff09;软件。建议采用matlab2013 Rb及以上版本打开。&#xff08;若需要其他版本可联系代为转换&#xff0c;高于该版本的matlab均可正…...

在51单片机上实现平滑呼吸灯:50us定时器PWM实战指南

在51单片机上实现平滑呼吸灯:50us定时器PWM实战指南 引言 本文将详细介绍如何在51单片机平台上,通过精确的50us定时器中断实现无闪烁的呼吸灯效果。相比常见的125us实现方案,50us定时器能提供更高的PWM频率和更细腻的亮度控制。 硬件设计 基本电路配置 主控芯片:SC92F8…...

asm汇编源代码之CPU型号检测

提供1个子程序: 1. CPU型号检测 CPUTYPE 无输入参数&#xff0c;返回值AX指示CPU类型(报歉,当时最新CPU型号只有80486) 函数的返回值详细描述如下 CPUTYPE PROC  FAR ;OUT: AX01, 8086; AX02, 80286; AX03, 80386; AX04, 80486 UP; ; more source code at http://www.ahj…...

提高课:数据结构之树状数组

1&#xff0c;楼兰图腾 #include<iostream> #include<cstring> #include<cstdio> #include<algorithm>using namespace std;typedef long long LL;const int N 200010;int n; int a[N]; int tr[N]; int Greater[N], lower[N];int lowbit(int x) {ret…...

python可变对象与不可变对象

文章目录 Python 中的可变对象与不可变对象不可变对象(Immutable Objects)可变对象(Mutable Objects)重要区别 Python 中的可变对象与不可变对象 在 Python 中&#xff0c;对象可以分为可变对象(mutable)和不可变对象(immutable)&#xff0c;这是 Python 中非常重要的概念&…...

C++学习之金融类安全传输平台项目git

目录 1.知识点概述 2.版本控制工具作用 3.git和SVN 4.git介绍 5.git安装 6.工作区 暂存区 版本库概念 7.本地文件添加到暂存区和提交到版本库 8.文件的修改和还原 9.查看提交的历史版本信息 10.版本差异比较 11.删除文件 12.本地版本管理设置忽略目录 13.远程git仓…...

果篮问题 Python

# 给你两个长度为 n 的整数数组&#xff0c;fruits 和 baskets&#xff0c;其中 fruits[i] 表示第 i 种水果的 数量&#xff0c;baskets[j] 表示第 j 个篮子的 容量。 # 你需要对 fruits 数组从左到右按照以下规则放置水果&#xff1a; # 每种水果必须放入第一个 容量大于等于 …...