快速入门 Logback

news2025/2/27 3:00:08

简介

Logback 旨在作为流行的 log4j 项目的继承者。它是由 log4j 创始人 Ceki Gulcu 设计的。同时它也是 SpingBoot 项目的默认日志框架。

安装

因为 logback 需要和 slf4j 一起使用,所以总共需要添加依赖的包有 slf4j-api.jar,logback-core.jar,logback-classic.jar,logback-access.jar 这个暂时用不到所以不添加依赖了。

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <logback.version>1.1.7</logback.version>
    <slf4j.version>1.7.21</slf4j.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>${slf4j.version}</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-core</artifactId>
        <version>${logback.version}</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>${logback.version}</version>
    </dependency>
</dependencies>

在 SpringBoot 项目中,如果你引入了 spring-boot-starter-web,那你已经引入了上述的所有依赖。

配置

Logback 的配置文件名为 logback.xml,在应用程序启动之后,Logback 会尝试在类路径中寻找该文件,如果没有找到,则会使用 Logback 内部的默认配置。

如果你的 logback.xml 配置文件在应用程序外部,可以通过环境变量 logback.configurationFile=/path/to/config.xml 来指定外部配置文件的路径。

configration

configuration 是 logback.xml 中的顶级元素,它包含了一些属性:

  • scan:布尔类型,如果为 true,则 Logback 会在配置文件修改之后自动重新加载配置。
  • scanPeriod:如果 scan 设置为 true,则可以使用该属性来配置 Logback 扫描配置文件是否变化的扫描周期。
  • debug:布尔类型,该属性表示是否打印 Logback 内部日志,如果为 true,则打印,默认为 false。
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="30 seconds" debug="false">
  ...
</configuration> 

上述实例中表示开启配置文件扫描,扫描周期为 30s,并且不打印 Logback 内部日志。

configuration 元素下有三个子元素 appender,logger,root,其中 appender 和 logger 可以是零个或多个,root 元素则做多只能有一个。
在这里插入图片描述

property

用于配置变量,配置的变量可以在 appender 和 logger 中通过 ${} 来使用,可以用于统一配置。

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    
    <property name="PATTERN" value="%-4relative [%thread] %-5level %logger{35} - %msg %n" /> 
    
   <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> 
      <encoder> 
         <pattern>${PATTERN}</pattern> 
      </encoder> 
   </appender> 

   <root level="DEBUG"> 
      <appender-ref ref="STDOUT" /> 
   </root> 
</configuration>

appender

appender 元素用来定义写日志的组件,它有两个必填的属性 name 和 class,name 表示组件的名称和 class 用于配置写日志逻辑的类,不同的类对应不同的写日志方式,目前,Logback 中定义了有 ConsoleAppender(控制台)、FileAppender(文件)、ServerSockerAppender(远程 Socker 服务器)、SMTPAppender(远程邮件服务器)、和 SyslogAppender(远程 Syslog 守护程序) 等 appender;当然,你也可以通过实现 Appender 接口来实现自己的 appender 并在配置文件中使用。

而这其中最常使用的就是 ConsoleAppender、FileAppender 和 RollingFileAppender。其中 RollingFileAppender 是 FileAppender 子类,它在日志写文件的基础上附加了滚动日志的功能,它解决了日志一直记录在一个文件而造成超大日志文件的痛点。

ConsoleAppender

<?xml version="1.0" encoding="UTF-8"?>
<configuration> 
   <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> 
      <encoder> 
         <pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern> 
      </encoder> 
   </appender> 

   <root level="DEBUG"> 
      <appender-ref ref="STDOUT" /> 
   </root> 
</configuration>

上述示例中的名为 STDOUT 的 appender 使用了 ConsoleAppender 来输出日志,即将日志输出到控制台上,其中的 <encoder> 子标签定对日志进行格式化。

FileAppender

<?xml version="1.0" encoding="UTF-8"?>
<configuration> 
  <appender name="FILE" class="ch.qos.logback.core.FileAppender"> 
    <file>testFile.log</file> 
    <append>true</append> 
    <encoder> 
      <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern> 
    </encoder> 
  </appender> 

  <root level="DEBUG"> 
    <appender-ref ref="FILE" /> 
  </root> 
</configuration>

上述示例中的名为 FILE 的 appender 使用了 FileAppender 来输出日志,即将日志输出到一个文件中,其中子标签释义如下:

  • file:记录日志的文件名,可以是相对目录也可以是绝对目录,如果上级目录不存在则自动创建
  • append:记录日志之前如果文件已经存在的行为,true 表示在现有文件的末尾追加日志,false 表示清空现有文件内容后写入日志,默认为 true
  • encoder:输出日志的格式

RollingFileAppender

<?xml version="1.0" encoding="UTF-8"?>
<configuration> 
    <appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> 
            <fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern> 
            <maxHistory>30</maxHistory> 
        </rollingPolicy> 
        <encoder> 
            <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern> 
        </encoder> 
    </appender> 

    <root level="DEBUG"> 
        <appender-ref ref="ROLLING_FILE" /> 
    </root> 
</configuration>

上述示例中名为 ROLLING_FILE 的 appender 使用 RollingFileAppender 来输出日志,使用的滚动策略是基于时间的滚动策略,其中子标签释义如下:

  • rollingPolicy:滚动策略,常见的滚动策略有基于时间的滚动策略 TimeBasedRollingPolicy、基于文件大小的滚动策略 SizeBasedTriggeringPolicy
  • encoder:输出日志的格式
基于时间的滚动策略

类是 ch.qos.logback.core.rolling.TimeBasedRollingPolicy,常用属性如下:

  • fileNamePattern:必填属性,用于设定新文件的文件名和每次滚动的时间周期,通过 %d 来只当滚动周期,如 logFile.%d{yyyy-MM-dd}.log 表示按天滚动,logFile.%d{yyyy-MM}.log 表示按月滚动,logFile.%d.log 表示按天滚动
  • maxHistory:可选属性,与 fileNamePattern 搭配使用,用于设置可以保留的日志文件的个数。例如如果日志文件 1 个月滚动一次,maxHistory 设置为 5 表示最大保留最近 5 个月的日志文件,如果日志文件 1 天滚动一次,maxHistory 设置为 30 表示最大保留最近 30 天的日志文件
  • totalSizeCap:可选属性,相当于按时间滚动日志的保险,用来控制所有日志文件的总大小,当总大小超过指定的值时,会删除最老的日志文件
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>logFile.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--             按天轮转 -->
            <fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--             保存 30 天的历史记录,最大大小为 3GB -->
            <maxHistory>30</maxHistory>
            <totalSizeCap>3GB</totalSizeCap>
        </rollingPolicy>
        <encoder>
            <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
        </encoder>
    </appender>
    <root level="DEBUG">
        <appender-ref ref="FILE" />
    </root>
</configuration>
基于时间和文件大小的滚动策略

类是 ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy,常用属性如下:

  • fileNamePattern:用法和基于时间的滚动策略一样,除了 %d,还需要使用 %i,用于解决没有到下一个滚动时间但是因为文件大小而触发的滚动,文件名一样的问题,%i 从 0 开始递增

  • maxFileSize:每个文件的最大大小,如果超过指定的值会触发滚动

  • maxHistory:用法和基于时间的滚动策略一样

  • totalSizeCap:用法和基于时间的滚动策略一样

logger

appender 标签用来配置日志的输出目的地,而 logger 标签可以看做日志的来源,即使从哪个包下或具体哪个类打印的日志,logger 标签可以绑定零个或多个 appender 来指定日志输出目的地。它有以下参数:

  • name:必填属性,指定一个包或具体的类
  • level:可选属性,日志的打印级别,如果没有指定则从父 logger 中继承
  • additivity:可选属性,是否向父 logger 传递日志,布尔类型,默认为 true,表示向父 logger 传递日志

logger 包含零个或多个子标签 <appender-ref> ,它用来绑定 appender。

在 logback 中,logger 具有树形结构的层级关系,这种层级关系通过包名来构建,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<configuration> 
   <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> 
      <encoder> 
         <pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern> 
      </encoder> 
   </appender>
    
    <logger name="com.test.logback" level="debug" additivity="true">
        <appender-ref ref="STDOUT" />
    </logger>
    
    <logger name="com.test" level="debug" additivity="true">
        <appender-ref ref="STDOUT" />
    </logger>

   <root level="debug"> 
   </root> 
</configuration>

上述两个 logger,通过包名的层级结构,name 为 com.test 的 logger 是 name 为 com.test.logback 的父 logger,如果通过包名的层级结构找不到该 logger 的父 logger,那么它的父 logger 就是 root logger,比如,name 为 com.test 的父 logger 就是 root logger,如果之后又定义了一个 name 为 com 的 logger,那么它的父 logger 会更变为新定义的 name 为 com 的 logger,而 name 为 com 的父 logger 就是 root logger。

通过上面介绍,我们 additivity 属性用于配置当前 logger 是否将日志传递给父 logger,默认为传递(true),以上面的例子来说,如果 com.test.logback 包下的类打印了日志,如果会传递到 name 为 com.test.logback 的 logger,并使用它绑定的 appender 来输出日志,又因为它的 additivity 的值为 true,那么当前 logger 在自己输出日志之后,还会将日志传递给父 logger,也就是 name 为 com.test 的 logger,不合理的使用 additivity 属性可能导致重复打印日志的情况。

其中 level 属性也与 logger 的层级结构有关,如果当前 logger 没有定义 level 属性,那么将会从最近的定义了 level 属性的父 logger 中继承,因此 root logger 一般都会设置 level 属性,用于给其他的 logger 统一设置 level 属性。

level 级别:

  • DEBUG:该级别通常用于开发和调试阶段,一般用它来记录详细的程序运行状态信息,比如输入输出、变量值的,这些信息对于排查文件很有帮助,但是在生产环境不建议开启。
  • INFO:该级别用于记录应用程序的重要事件和状态信息,这些信息对于监控和了解应用程序的运行状态非常有用,通常,生成环境会启用该日志级别。
  • WARN:该级别记录潜在的问题和警告信息,这些信息表明应用程序可能会出现问题,但不一定致命。这些日志可以帮助你及时发现潜在的风险。
  • ERROR:该级别用于记录错误事件,例如异常或应用程序中的错误,这些日志通常表明应用程序遇到了问题,需要进行故障排查。
  • FATAL:该级别表示非常严重的错误,通常会导致应用程序无法继续运行。

优先级从高到低依次是:FATAL -> ERROR -> WARN -> INFO -> DEBUG,开启指定的日志级别,会打印该日志级别的日志和所有优先级高于该日志级别的日志,如设置日志级别是 INFO,那么会打印 FATAL,ERROR,WARN 和 INFO 级别的日志,如果设置日志级别是 WARN,那么会打印 FATAL,ERRO 和 WARN 级别的日志。

验证 logger 的层级关系

通过实例来验证上述中 logger 的层级关系,首先创建两个类 com.test.Logback01Testscom.test.logback.Logback02Tests。类定义中省略了 package 和 import 语句。

com.test.Logback01Tests

public class Logback01Tests {

    private static final Logger log = LoggerFactory.getLogger(Logback01Tests.class);

    public void test01(){

        log.debug("debug");
        log.info("info");

    }
}

com.test.logback.Logback02Tests

public class Logback02Tests {

    private static final Logger log = LoggerFactory.getLogger(Logback02Tests.class);

    public void test01(){
        log.debug("debug");
        log.info("info");
    }

}

logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
       
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
      <encoder>
         <pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
      </encoder>
   </appender>

    <logger name="com.test.logback" level="debug" additivity="true">
        <appender-ref ref="STDOUT" />
    </logger>

    <logger name="com.test" level="debug" additivity="true">
        <appender-ref ref="STDOUT" />
    </logger>

   <root level="debug">
   </root>
</configuration>

通过 logback.xml 配置预测日志的输出结果。

因为两个 logger 都设置了 debug 日志级别,所以方法中打印的 debug 和 info 级别两条日志都会打印出来,然后都设置了将日志传递到父 logger 中,则 name 为 com.test.logback 的 logger 会将日志传递到 name 为 com.test 父 logger 中,所以 com.test.logback.Logback02Tests 中的两条日志应该会打印两次,name 为 com.test 的 logger 会将日志传递到 root logger 中,但是 root logger 没有绑定任何的 appender,所以即使传递了也不会打印日志,所以 com.test.Logback01Tests 中的四条日志(加上子 logger 中传递过来的两条日志)应该只会打印一次。

定义一个测试方法调用两个类的方法。

public class NormalTests {

    @Test
    public void test02(){
        Logback01Tests logback01Tests = new Logback01Tests();
        Logback02Tests logback02Tests = new Logback02Tests();

        logback01Tests.test01();
        logback02Tests.test01();
    }
}

实际输出结果:

127  [main] DEBUG com.test.Logback01Tests - debug 
129  [main] INFO  com.test.Logback01Tests - info 
129  [main] DEBUG com.test.logback.Logback02Tests - debug 
129  [main] DEBUG com.test.logback.Logback02Tests - debug 
129  [main] INFO  com.test.logback.Logback02Tests - info 
129  [main] INFO  com.test.logback.Logback02Tests - info 

可以看到输出结果完全符合我们的预期,读者可以通过扩展这个例子来验证其他的一些问题,如将日志级别设置成 INFO 之后的日志输出应该是怎么样的?

root

root 标签用来配置 root logger,它只有一个属性,即 level 属性。与 logger 元素类似,root 元素可以包含零个或多个 <appender-ref> 子标签。

在实际使用中,root logger 通常不会绑定 appender,以避免日志重复打印,日志打印被分配到各个子 logger 中来负责。root logger 中会定义一个 level,以保证每个子 logger 都能继承 level。

完整示例

<configuration>
    <!--本文主要输出日志为控制台日志,系统日志,sql日志,异常日志-->
    <!-- %m输出的信息,%p日志级别,%t线程名,%d日期,%c类的全名,,,, -->
    <!--控制台-->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d %p (%file:%line\)- %m%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!--系统info级别日志-->
    <!--<File> 日志目录,没有会自动创建-->
    <!--<rollingPolicy>日志策略,每天简历一个日志文件,或者当天日志文件超过64MB时-->
    <!--encoder 日志编码及输出格式-->
    <appender name="fileLog"
              class="ch.qos.logback.core.rolling.RollingFileAppender">
        <File>log/file/fileLog.log</File>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>log/file/fileLog.log.%d.%i</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <!-- or whenever the file size reaches 64 MB -->
                <maxFileSize>64 MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <encoder>
            <pattern>
                %d %p (%file:%line\)- %m%n
            </pattern>
            <charset>UTF-8</charset>
            <!-- 此处设置字符集 -->
        </encoder>
    </appender>

    <!--sql日志-->
    <appender name="sqlFile"
              class="ch.qos.logback.core.rolling.RollingFileAppender">
        <File>log/sql/sqlFile.log</File>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>log/sql/sqlFile.log.%d.%i</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <!-- or whenever the file size reaches 64 MB -->
                <maxFileSize>64 MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <!--对记录事件进行格式化。负责两件事,一是把日志信息转换成字节数组,二是把字节数组写入到输出流。-->
        <encoder>
            <!--用来设置日志的输入格式-->
            <pattern>
                %d %p (%file:%line\)- %m%n
            </pattern>
            <charset>UTF-8</charset>
            <!-- 此处设置字符集 -->
        </encoder>
    </appender>


    <!--异常日志-->
    <appender name="errorFile"
              class="ch.qos.logback.core.rolling.RollingFileAppender">
        <File>log/error/errorFile.log</File>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>log/error/errorFile.%d.log.%i</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <!-- or whenever the file size reaches 64 MB -->
                <maxFileSize>64 MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <!--对记录事件进行格式化。负责两件事,一是把日志信息转换成字节数组,二是把字节数组写入到输出流。-->
        <encoder>
            <!--用来设置日志的输入格式-->
            <pattern>
                %d %p (%file:%line\)- %m%n
            </pattern>
            <charset>UTF-8</charset>
            <!-- 此处设置字符集 -->
        </encoder>
        <!--
            日志都在这里 过滤出 error
            使用 try {}catch (Exception e){} 的话异常无法写入日志,可以在catch里用logger.error()方法手动写入日志
            -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <!--  日志输出级别 -->
    <!--All\DEBUG\INFO\WARN\ERROR\FATAL\OFF-->
    <!--打印info级别日志,分别在控制台,fileLog,errorFile输出
        异常日志在上面由过滤器过滤出ERROR日志打印
    -->
    <root level="INFO">
        <appender-ref ref="fileLog" />
        <appender-ref ref="console" />
        <appender-ref ref="errorFile" />
    </root>

    <!--打印sql至sqlFile文件日志-->
    <logger name="com.springboot.demo.mapper" level="DEBUG" additivity="false">
        <appender-ref ref="console" />
        <appender-ref ref="sqlFile" />
    </logger>
</configuration>

SpringBoot 中的日志

SpringBoot 项目的默认日志框架就是 Logback,在 SpingBoot 项目中可以通过 application.properties 来配置日志的打印行为。

# 设置logback.xml位置
logging.config=classpath:log/logback.xml

# 为不同的包名设置不同的打印级别
# org.springframework.web 包的打印级别为 debug
logging.level.org.springframework.web=debug
# org.hibernate 包的打印级别为 error
logging.level.org.hibernate=error

# 指定日志文件的名称
logging.file.name=springboot.log
# 指定日志文件的全路径,它包含了指定日志文件名称的功能
logging.file.name=/usr/log/springboot.log

参考:
https://logback.qos.ch/manual/index.html

https://blog.csdn.net/weixin_41377777/article/details/120962037

https://www.cnblogs.com/gavincoder/p/10091757.html

https://juejin.cn/post/6844903841318567949

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/990538.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

sql:SQL优化知识点记录(十四)

&#xff08;1&#xff09;索引失效行锁变表锁 建立2个索引 索引是失效后&#xff0c;系统性能会变查&#xff0c;如果涉及到锁的话&#xff0c;行锁会变表锁 有一个问题&#xff0c;当session1用b字段做查询条件因为是varchar类型&#xff0c;需要加双引号&#xff0c;但是没…

开源知识库平台Raneto

什么是 Raneto &#xff1f; Raneto 是一个开源知识库平台&#xff0c;它使用静态 Markdown 文件来支持您的知识库。 官方提供了 doc & demo 网站&#xff0c;即是帮助文档&#xff0c;也是个 demo&#xff0c;地址&#xff1a;https://docs.raneto.com 准备 项目使用con…

摆动输入连杆夹持机构

1、运动与受力分析 import sympy as sy import numpy as np import matplotlib.pyplot as plt a,a1,b,b1,c,c1,d2,d3,fi,F,L,e sy.symbols(a,a1,b,b1,c,c1,d2,d3,fi,F,L,e)A(-d2,0) D(0,d3) B(-d2a*cos(fi),a*sin(fi)) C(-c*cos(pu),d3c*sin(pu)) B(-d2a*cos(fipi),a*sin(fipi…

K8S原理架构与实战教程

文章目录 一、背景1.1 物理机时代、虚拟机时代、容器化时代1.2 容器编排的需要 二、K8S架构2.2 Worker节点 三、核心概念3.1 Pod3.2 Deployment3.3 Service3.4 Volume3.5 Namespace 四、K8S安装五、kubectl常用命令六、K8S实战6.1 水平扩容6.2 自动装箱6.2.1 节点污点6.2.2 Pod…

Java多线程(二)线程安全

线程安全 线程安全&#xff08;风险&#xff09; 线程不安全的原因&#xff1a; 解决线程不安全&#xff1a; synchronized 内存刷新 可重入 volatile 关键字 wait 和 notify wait&#xff08;&#xff09; notify &#xff08;&#xff09; wait与sleep的区别&…

C# OpenVino Yolov8 Seg 分割

效果 项目 代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using OpenCvSharp;namespace OpenVino_Yolov8_Demo {public…

30天入门Python(基础篇)——第2天:Python安装(保姆级)与IDE的认识与选择+详细安装教程

文章目录 专栏导读上一节课回顾1、Python解释器的安装查看各个版本的Python解释器①、ok,双击安装②、这里我们选择【自定义】安装&#xff0c; 下面的【将Python添加在环境变量】大家一定要打个勾③、点击【Next】进行下一步④、这里不建议安装在C盘, 点击【Browse】我在F盘创…

『SpringBoot 源码分析』run() 方法执行流程:(3)刷新应用上下文-处理 @ComponentScan 注解

『SpringBoot 源码分析』run() 方法执行流程&#xff1a;&#xff08;3&#xff09;刷新应用上下文-处理 ComponentScan 注解 基于 2.2.9.RELEASE问题&#xff1a;当方法进行了注释标记之后&#xff0c;springboot 又是怎么注入到容器中并创建类呢&#xff1f; 首先创建测试主…

linux--进程--system与popen函数

1.system #include <stdlib.h>int system(const char *command); 返回值&#xff1a; 成功&#xff0c;则返回进程的状态值&#xff1b;不能源码execl函数&#xff0c;返回127&#xff1b;失败返回-1&#xff1b; 不能成功运行分析文章&#xff1a;linux下system函数详…

Java网络编程(二)Socket 套接字(TCP和UDP),以及TCP的回显

Socket 套接字 我们软件工作者&#xff0c;着重编写的是应用层的代码&#xff0c;但是发送这个数据&#xff0c;我们就需要将应用层传输到传输层&#xff0c;也就意味着我们需要调用应用层的API&#xff0c;统称为 Socket API。 套接字的分类&#xff1a; 流套接字&#xff…

2023数学建模国赛B题完整论文来啦!(含一二问求解代码及三四问仿真模拟代码)

大家好呀&#xff0c;从昨天发布赛题一直到现在&#xff0c;总算完成了全国大学生数学建模竞赛B题完整的成品论文。 本论文可以保证原创&#xff0c;保证高质量。绝不是随便引用一大堆模型和代码复制粘贴进来完全没有应用糊弄人的垃圾半成品论文。 说实话团队通宵一直到现在做…

汇川PLC学习Day1:跑马灯程序编写

汇川PLC学习Day1&#xff1a;跑马灯程序编写 一、 软件安装 进入官网下载软件 二、 使用帮助 三、 新建工程与功能代码实现 CtrlN 寻找内带输出模块的CPU并设置好工程名字与保存路径&#xff0c;语言选择想熟悉的类型 工程建立后&#xff0c;PLC_PRG即为用户编写程序文件…

【疑难杂症】解决 git 文件夹不显示绿色图标和红色图标的问题

目录 一、问题描述 二、问题解决前提 【2.1】首先保证电脑本机上有TortoiseGit这个软件 【2.2】TortoiseGit下载官网 【2.3】根据自己电脑位数进行下载&#xff0c;这里下载的是64位 【2.4】下载好之后&#xff0c;一路next进行安装&#xff0c;配置自己的邮箱和用户名 …

uni-app:重置表单数据

效果 代码 <template><form><input type"text" v-model"inputValue" placeholder"请输入信息"/><input type"text" v-model"inputValue1" placeholder"请输入信息"/><input type&quo…

用Python登录账户

1 问题 如何利用python登录账户&#xff1f; 2 方法 账户和密码存放在文件夹中从文件夹中读取并比较密码密文验证三次后&#xff0c;如不成功则锁定用户 通过。。。。。。。。等证明提出的方法是有效的&#xff0c;能够解决开头提出的问题。 代码清单 1 import osimport getpas…

FGO:使用chaIdea获取抽卡数据(mitmproxy抓包)

需求描述 最近逛贴吧看到好多master贴出自己的抽卡概率截图&#xff0c;本非洲杂鱼master也对自己的脸黑程度产生了好奇&#xff08;曾经15单芭娜娜池子1五星&#xff0c;6单道满池子1五星&#xff0c;梅莉池子330抽1五星&#xff0c;最近的芭娜娜复刻又330抽1五星&#xff09…

流程图用什么软件做比较好?这几个实用软件了解下

流程图用什么软件做比较好&#xff1f;流程图的制作对于企业管理、项目管理、产品设计等领域都非常重要。制作流程图可以帮助我们更好地理解事物之间的关系和流程&#xff0c;从而规划和组织工作。因此&#xff0c;选择一个合适的流程图软件是非常必要的。下面就给大家介绍几种…

C++中使用R“()“标记符书写多行字符串

在C#中使用表示的字符串能够跨越数行。用于在C#中写JS或SQL代码比较方便。 string sqlInsert "INSERT INTO tb_param(protocol, slave, number, ptype, pid, name, format) VALUES(2, 24, 0, 1, 1, a04005, .3);INSERT INTO tb_param(protocol, slave, number, ptype, …

day52(补)

300.最长递增子序列 力扣题目链接(opens new window) 给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。 子序列是由数组派生而来的序列&#xff0c;删除&#xff08;或不删除&#xff09;数组中的元素而不改变其余元素的顺序。例如&#xff0c;[3,6,2…

ZFS了解

存储数据的管理通常涉及两个方面:对一个或多个块存储设备(如硬盘驱动器和SD卡)进行物理卷管理&#xff0c;并将它们组织成操作系统所看到的逻辑块设备(通常涉及卷管理器、RAID控制器、阵列管理器或合适的设备驱动程序)&#xff0c;以及对存储在这些逻辑块设备(文件系统或其他数…