【Log日志】springboot项目中集成Log日志详解

2023-10-31

一、Log日志介绍

我们先看看springboot项目启动时的那么多信息是什么呢?如下图:

在这里插入图片描述
注意INFO! 这个呢其实就是日志。它是springboot的日志框架,默认集成Logback .
默认情况下,Spring Boot会用Logback来记录日志,并用INFO级别输出到控制台。

从上图可以看到,日志输出内容元素具体如下:

  • 时间日期:精确到毫秒
  • 日志级别:ERROR, WARN, INFO, DEBUG or TRACE
  • 进程ID
  • 分隔符:— 标识实际日志的开始
  • 线程名:方括号括起来(可能会截断控制台输出)
  • Logger名:通常使用源代码的类名
  • 日志内容

1.Log 日志组件主要作用及用途

日志最大的功能点:对于学习程序,测试的工程师来说,日志能够定位问题,解决问题。

(1)定位问题 日志可以帮助程序员调试问题,帮助测试人员定位问题
(2)记录一切 日志帮助我们记录程序功能都干了什么,无论是正常的输入输出还是出现异常,都可以用日志记录!
(3)记录分析用户行为 统计分析师用来记录用户的一起行为,用于分析用户的习惯和商业价值
(4)备份和还原实时数据 数据库工程师用来作为一种特殊的数据库

2.日志的级别Level

日志也有轻重缓急之分,日志级别从低到高分为:

TRACE < DEBUG < INFO < WARN < ERROR < FATAL

日志级别 使用场景
DEBUG debug级别用来记录详细的信息,方便定位问题进行调试,在生产环境我们一般不开启DEBUG
INFO 用来记录关键代码点的信息,以便代码是否按照我们预期的执行,生产环境通常会设置INFO级别
WARN 记录某些不预期发生的情况,如磁盘不足
ERROR 由于一个更严重的问题导致某些功能不能正常运行时记录的信息
FATAL 当发生严重错误,导致应用程序不能继续运行时记录的信息

日志级别越高输出的日志信息越少,不会输出比它级别低的信息!

如果设置为 WARN ,则低于 WARN 的信息都不会输出。

Spring Boot中默认配置ERROR、WARN和INFO级别的日志输出到控制台。

我们可以通过启动应用程序 --debug 标志来启用“调试”模式(开发的时候推荐开启),以下两种方式皆可:

  • 在运行命令后加入--debug标志,如:$ java -jar springTest.jar --debug
  • 在application.properties中配置debug=true,该属性置为true的时候,核心Logger(包含嵌入式容器、hibernate、spring)会输出更多内容,但是你自己应用的日志并不会输出为DEBUG级别。

级别控制

所有支持的日志记录系统都可以在Spring环境中设置记录级别(例如在application.properties中或者application.yml)
格式为:logging.level.* = LEVEL

  1. logging.level:日志级别控制前缀,*为包名或Logger名
  2. LEVEL:选项TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF

如:

logging.level.com.itfuture=INFO:com.itfuture包下所有classINFO级别输出
logging.level.root=WARN:root日志以WARN级别输出

3.日志的输出Import

通常日志以文本流的形式存储在磁盘,也可以把日志存储在关系型数据库中或 No Sql 中

  • 文本
  • 关系型数据库
  • No Sql
  • Console 控制台

一般日志组件都可以自定义输出格式。

3.1 快速使用

一般这样写:
在这里插入图片描述

如果每次都写这行代码会很麻烦,可以使用注解,但是需要使用lombok(导入lombok依赖):
在这里插入图片描述

可以使用{} 占位符来拼接字符串,而不需要使用+来连接字符串:

log.info("name:{},age:{}",name,age)

3.2 日志文件输出

默认情况下,Spring Boot将日志输出到控制台,不会写到日志文件。

使用Spring Boot在application.properties或application.yml配置,这样只能配置简单的场景,保存路径、日志格式等,复杂的场景(区分 info 和 error 的日志、每天产生一个日志文件等)满足不了,只能自定义配置

如:

# log日志配置
logging:
  #level 日志等级 指定命名空间的日志输出
  level:
    com.itfuture.e.controller: ERROR
  #pattern 指定输出场景的日志输出格式
  pattern:
    console: "%d - %msg%n"
  path: "/var/log" #废弃,不推荐
  #file 指定输出文件的存储路径
  file:
    path: "./"
    max-history: 7 #日志保留天数
    clean-history-on-start: false
    name: "e-Spring.log" # 日志文件名称

总结

如果要编写除控制台输出之外的日志文件,则需在application.properties中设置logging.filelogging.path属性。

logging.file,设置文件的一些配置,比如清除历史、日志大小等,可以是绝对路径,也可以是相对路径。如:logging.file=my.log
logging.path,设置目录,会在该目录下创建spring.log文件,并写入日志内容,如:logging.path=/var/log
如果只配置 logging.file,会在项目的当前路径下生成一个 xxx.log 日志文件。
如果只配置 logging.path,在 /var/log文件夹生成一个日志文件为 spring.log.

注:二者不能同时使用,如若同时使用,则只有logging.file生效 默认情况下,日志文件的大小达到10MB时会切分一次,产生新的日志文件,默认级别为:ERROR、WARN、INFO

3.3 自定义配置

根据不同的日志系统,你可以按如下规则组织配置文件名,就能被正确加载:

Logback:logback-spring.xml, logback-spring.groovy, logback.xml, logback.groovy
Log4j:log4j-spring.properties, log4j-spring.xml, log4j.properties, log4j.xml
Log4j2:log4j2-spring.xml, log4j2.xml
JDK (Java Util Logging):logging.properties

Spring Boot官方推荐优先使用带有-spring的文件名作为你的日志配置(如使用logback-spring.xml,而不是logback.xml),命名为logback-spring.xml的日志配置文件,spring boot可以为它添加一些spring boot特有的配置项(下面会提到)。
默认的命名规则,并且放在 src/main/resources 下面即可

如果你即想完全掌控日志配置,但又不想用logback.xml作为Logback配置的名字,application.yml可以通过logging.config属性指定自定义的名字:

logging.config=classpath:logging-config.xml

    虽然一般并不需要改变配置文件的名字,但是如果你想针对不同运行时Profile使用不同的日志配置,这个功能会很有用。
    一般不需要这个属性,而是直接在logback-spring.xml中使用springProfile配置,不需要logging.config指定不同环境使用不同配置文件。springProfile配置在下面介绍。

根据下面文件实例进行分析:

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
	<!--设置上下文名称-->
	<!--每个logger都关联到logger上下文,默认上下文名称为“default”。
	但可以使用设置成其他名字,用于区分不同应用程序的记录。
	一旦设置,不能修改,可以通过%contextName来打印日志上下文名称
	-->
   <contextName>logback</contextName>
   
   <!--输出到控制台-->
   <!--
   appender用来格式化日志输出节点,有俩个属性name和classclass用来指定哪种输出策略,常用就是控制台输出策略和文件输出策略。
   -->
   <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
       <!--<encoder>表示对日志进行编码-->
       <encoder>
           <!--格式化输出:%d{HH: mm:ss.SSS}表示日期,%thread表示线程名,%-5level:日志级别,并且使用5个字符靠左对齐,
           %logger{36}:日志输出者的名字,%msg:日志消息,%n是平台换行符
           -->
           <pattern>%d{HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
           <charset>UTF-8</charset>
       </encoder>
   </appender>

   <!--按天生成日志-->
   <!--随着应用的运行时间越来越长,日志也会增长的越来越多-->
   <!--RollingFileAppender用于切分文件日志-->
   <appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <!--如果只是想要 Info 级别的日志,只是过滤 info 还是会输出 Error 日志,因为 Error 的级别高,
    所以我们使用下面的策略,可以避免输出 Error 的日志-->
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
        <!--过滤 Error-->
        <level>ERROR</level>
        <!--匹配到就禁止-->
        <onMatch>DENY</onMatch>
        <!--没有匹配到就允许-->
        <onMismatch>ACCEPT</onMismatch>
    </filter>
    <!--日志名称,如果没有File 属性,那么只会使用FileNamePattern的文件路径规则
        如果同时有<File><FileNamePattern>,那么当天日志是<File>,明天会自动把今天
        的日志改名为今天的日期。即,<File> 的日志都是当天的。
    -->
    <File>${logback.logdir}/info.${logback.appname}.log</File>
    <!--滚动策略,按照时间滚动 TimeBasedRollingPolicy-->
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <!--文件路径,定义了日志的切分方式——把每一天的日志归档到一个文件中,以防止日志填满整个磁盘空间-->
        <FileNamePattern>${logback.logdir}/info.${logback.appname}.%d{yyyy-MM-dd}.log</FileNamePattern>
        <!--只保留最近90天的日志-->
        <maxHistory>90</maxHistory>
        <!--用来指定日志文件的上限大小,那么到了这个值,就会删除旧的日志-->
        <!--<totalSizeCap>1GB</totalSizeCap>-->
    </rollingPolicy>
    <!--日志输出编码格式化-->
    <encoder>
        <charset>UTF-8</charset>
        <pattern>%d [%thread] %-5level %logger{36} %line - %msg%n</pattern>
    </encoder>
</appender>


<appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <!--如果只是想要 Error 级别的日志,那么需要过滤一下,默认是 info 级别的,ThresholdFilter-->
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <level>Error</level>
    </filter>
    <!--日志名称,如果没有File 属性,那么只会使用FileNamePattern的文件路径规则
        如果同时有<File><FileNamePattern>,那么当天日志是<File>,明天会自动把今天
        的日志改名为今天的日期。即,<File> 的日志都是当天的。
    -->
    <File>${logback.logdir}/error.${logback.appname}.log</File>
    <!--滚动策略,按照时间滚动 TimeBasedRollingPolicy-->
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <!--文件路径,定义了日志的切分方式——把每一天的日志归档到一个文件中,以防止日志填满整个磁盘空间-->
        <FileNamePattern>${logback.logdir}/error.${logback.appname}.%d{yyyy-MM-dd}.log</FileNamePattern>
        <!--只保留最近90天的日志-->
        <maxHistory>90</maxHistory>
        <!--用来指定日志文件的上限大小,那么到了这个值,就会删除旧的日志-->
        <!--<totalSizeCap>1GB</totalSizeCap>-->
    </rollingPolicy>
    <!--日志输出编码格式化-->
    <encoder>
        <charset>UTF-8</charset>
        <pattern>%d [%thread] %-5level %logger{36} %line - %msg%n</pattern>
    </encoder>
</appender>

	<!--<loger>用来设置某一个包或者具体的某一个类的日志打印级别、以及指定<appender>-->
	<!--name:用来指定受此loger约束的某一个包或者具体的某一个类。
		level:用来设置打印级别
		addtivity:是否向上级loger传递打印信息。默认是true
	-->
   <logger name="com.fishpro.log" additivity="false">
       <appender-ref ref="console"/>
       <appender-ref ref="logFile"/>
   </logger>
   
   <!-- 设置Spring&Hibernate日志输出级别 -->
   <logger name="org.springframework" level="WARN"/>
   <logger name="org.mybatis" level="WARN"/> 
   <logger name="com.ibatis" level="DEBUG"/> 
   <logger name="com.ibatis.common.jdbc.SimpleDataSource" level="DEBUG"/> 
   <logger name="com.ibatis.common.jdbc.ScriptRunner" level="DEBUG"/> 
   <logger name="com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate" level="DEBUG"/>


      
   <logger name="java.sql.Connection" level="DEBUG"/>  
   <logger name="java.sql.Statement" level="DEBUG"/> 
   <logger name="java.sql.PreparedStatement" level="DEBUG"/> 
   <logger name="com.ruidou.baoqian.mapper" level="DEBUG"/>

   <!-- 开发环境下的日志配置 -->
   <!--root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性。-->
   <!-- 默认是DEBUG。可以包含零个或多个元素,标识这个appender将会添加到这个loger。-->
   <root level="error">
       <!--appender将会添加到这个loger-->
       <appender-ref ref="console"/>
       <appender-ref ref="logFile"/>
   </root>
</configuration>

多环境日志输出

<configuration>
    ...
    
    <!-- 测试环境+开发环境. 多个使用逗号隔开. -->
    <springProfile name="test,dev">
        <logger name="com.example.demo.controller" level="DEBUG" additivity="false">
            <appender-ref ref="consoleLog"/>
        </logger>
    </springProfile>
    
    <!-- 生产环境. -->
    <springProfile name="prod">
        <logger name="com.example.demo.controller" level="INFO" additivity="false">
            <appender-ref ref="consoleLog"/>
        </logger>
    </springProfile>
</configuration>

4. Spring Boot 日志组件 Log Plugin

当然自己开发日志组件也是可以的,实际上也不是很难,在一些特殊场景,很多公司都是用自己开发的日志组件,但是对于大多数应用来说,我们使用标准的日志组件就可以解决我们的问题。

Spring Boot 日志组件最为常见的包括了

Logback Spring Boot 约定的默认配置
log4j
log4j2
slf4j
JUL

大部分场景我们都是推荐 Spring Boot 自带的日志logback

二、Spring Boot Logback

Logback是由log4j创始人设计的又一个开源日志组件。目前,logback分为三个模块:logback-core,logback-classic和logback-access。是对log4j日志展示进一步改进

在 Spring Boot 中,logback 是基于 slf4j 实现的。

slf4j的全称是Simple Loging Facade For Java,即它仅仅是一个为Java程序提供日志输出的统一接口,并不是一个具体的日志实现方案,他能够实现大部分 日志组件。

logback 中使用了 slf4j,logback-classic.jar,logback-core.jar 实现了 logback 日志功能。

1.依赖配置 Pom.xml

网上不少人贴出了 logback 的依赖配置,实际上从依赖包中可以看出,默认是不需要单独配置 logback 依赖的。不需要单独配置、不需要单独配置、不需要单独配置

2.使用 YML 配置 logback

2.1 编写一个 Controller 层类作为测试用 IndexController


@Controller
public class IndexController {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    @RequestMapping("/")
    String index(){
        logger.debug("This is a debug message");
        logger.info("This is an info message");
        logger.warn("This is a warn message");
        logger.error("This is an error message");
        return "index";
    }
}

根据日志输出结果可以看出,我们没有 DEBUG 的日志,也就是说 logger.debug("This is a debug message"); 没有被输出到控制台。

实际上,Spring Boot 是一种约定大于配置,也就是说,它本身有一个配置文件叫base.xml,在这个配置文件里面,已经默认配置了输出的日志级别 让我们来看看 base.xml ,如下面的 xml 代码所示,root level=“INFO” 已经定义了日志输出级别为 INFO 。这就是为什么,我看到控制台没有输出 DEBUG 那条日志。

<?xml version="1.0" encoding="UTF-8"?>

<!--
Base logback configuration provided for compatibility with Spring Boot 1.1
-->

<included>
  <include resource="org/springframework/boot/logging/logback/defaults.xml" />
  <property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}}/spring.log}"/>
  <include resource="org/springframework/boot/logging/logback/console-appender.xml" />
  <include resource="org/springframework/boot/logging/logback/file-appender.xml" />
  <root level="INFO">
    <appender-ref ref="CONSOLE" />
    <appender-ref ref="FILE" />
  </root>
</included>

2.2 在 application.yml 中配置
如下配置,设置level的级别为 DEBUG

logging:
  level:
    com.fishpro.log: debug

运行结果可知,可以看出已经有了 DEBUG 日志。

2.3 在 application.yml 详细配置

logging:
  #level 日志等级 指定命名空间的日志输出
  level:
    com.fishpro.log: debug
  #file 指定输出文件的存储路径
  file: logs/app.log
  #pattern 指定输出场景的日志输出格式
  pattern:
    console: "%d %-5level %logger : %msg%n"
    file: "%d %-5level [%thread] %logger : %msg%n"

同时我们可以看到在项目根路径下多处理 logs 文件夹,下面有 app.log 文件,app.log 文件同时记录了日志的输出。

2.4 不同环境中配置

我们可以在 dev、prod、test 等环境中配置不同的 log 配置项目,我们只需要根据我们的配置文件来设置即可。

关于如何在 Spring Boot 中配置不同的环境实现 开发环境(dev)、测试环境(test)、生成环境(prod)分离,请参考Spring Boot 中多环境配置

3.使用 logback-spring.xml 来配置 logback 日志

如果需要更为详细的自定义 logback 日志,那么我们需要使用 xml 配置文件来配置。

使用logback-spring.xml来自定义日志的配置,主要需要了解 logback-spring.xml 详细功能点,能够配置哪些内容。

3.1指定 logback-spring.xml 路径

首先我们要知道 logback-spring.xml 文件放在哪里。

默认 logback-spring.xml 路径在 resource 文件夹下,即你只要在 resource 文件夹下新建文件 logback-spring.xml 即可。

3.2使用 logback-spring.xml 自定义配置
这里我们使用自定义配置 实现:
    1.把日志输出到指定的目录,并按照日期 yyyy-MM-dd 的格式按天存储,注意如果没有特别指定,这里的目录 applog 就是指项目的根目录(如果您的项目是多模块配置并不是指模块的目录)
    2.配置 xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
   <contextName>logback</contextName>
   <!--输出到控制台-->
   <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
       <encoder>
           <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
           <pattern>%d{HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
           <charset>UTF-8</charset>
       </encoder>
   </appender>

   <!--按天生成日志-->
   <appender name="logFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
       <Prudent>true</Prudent>
       <!-- 过滤器,只打印ERROR级别的日志 -->
       <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
           <!--日志文件输出的文件名-->
           <FileNamePattern>
               applog/%d{yyyy-MM-dd}/%d{yyyy-MM-dd}.log
           </FileNamePattern>
           <!--日志文件保留天数-->
           <MaxHistory>15</MaxHistory>
       </rollingPolicy>
       <layout class="ch.qos.logback.classic.PatternLayout">
           <Pattern>
               %d{yyyy-MM-dd HH:mm:ss} -%msg%n
           </Pattern>
       </layout>
   </appender>

   <logger name="com.fishpro.log" additivity="false">
       <appender-ref ref="console"/>
       <appender-ref ref="logFile"/>
   </logger>
   
   <!-- 设置Spring&Hibernate日志输出级别 -->
   <logger name="org.springframework" level="WARN"/>
   <logger name="org.mybatis" level="WARN"/> 
   <logger name="com.ibatis" level="DEBUG"/> 
   <logger name="com.ibatis.common.jdbc.SimpleDataSource" level="DEBUG"/> 
   <logger name="com.ibatis.common.jdbc.ScriptRunner" level="DEBUG"/> 
   <logger name="com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate" level="DEBUG"/>


      
   <logger name="java.sql.Connection" level="DEBUG"/>  
   <logger name="java.sql.Statement" level="DEBUG"/> 
   <logger name="java.sql.PreparedStatement" level="DEBUG"/> 
   <logger name="com.ruidou.baoqian.mapper" level="DEBUG"/>

   <!-- 开发环境下的日志配置 -->
   <root level="error">
       <appender-ref ref="console"/>
       <appender-ref ref="logFile"/>
   </root>
</configuration>


运行结果
运行后发现,工程根目录多出来 applog 文件夹,applog/2022-11-18/2022-11-18.log 按照日期分类来记录文件,这很重要。

优先级
有趣的是,当我们把 xml 文件同 application.yml 都进行配置的时候,他执行了 logback-spring.xml 中的配置,所有 logback-spring.xml 配置是优先的

想要知道logback-spring.xml配置的具体意义,请阅读本篇第 ·3.3 自定义配置

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Log日志】springboot项目中集成Log日志详解 的相关文章

  • java.lang.ClassNotFoundException:javax.mail.MessagingException

    我想使用 eclipse 将电子邮件从我的 gmail 帐户发送到另一个邮件帐户 我使用 apache tomcat 7 0 34 作为我的 Web 服务器 并使用端口 8080 作为 apache 服务器 HTTP 1 1 并使用 JRE
  • 如何在 JavaFX 中连接可观察列表?

    我所说的串联是指获得一个新列表 该列表侦听所有串联部分的更改 方法的目的是什么FXCollections concat ObservableList
  • 两个整数乘积的模

    我必须找到c c a b mod m a b c m 是 32 位整数 但 a b 可以超过 32 位 我正在尝试找出一种计算 c 的方法 而不使用 long 或任何 gt 32 位的数据类型 有任何想法吗 如果m是质数 事情可以简化吗 注
  • 垃圾收集器如何在幕后工作来收集死对象?

    我正在阅读有关垃圾收集的内容 众所周知 垃圾收集会收集死亡对象并回收内存 我的问题是 Collector 如何知道任何对象已死亡 它使用什么数据结构来跟踪活动对象 我正在研究这个问题 我发现GC实际上会跟踪活动对象 并标记它们 每个未标记的
  • eclipse行号状态行贡献项是如何实现的?

    我需要更新状态行编辑器特定的信息 我已经有了自己的实现 但我想看看 eclipse 贡献项是如何实现的 它显示状态行中的行号 列位置 谁能指点一下 哪里可以找到源代码 提前致谢 亚历克斯 G 我一直在研究它 它非常复杂 我不确定我是否了解完
  • 如何在 Java 中向时间戳添加/减去时区偏移量?

    我正在使用 JDK 8 并且玩过ZonedDateTime and Timestamp很多 但我仍然无法解决我面临的问题 假设我得到了格式化的Timestamp在格林威治标准时间 UTC 我的服务器位于某处 假设它设置为Asia Calcu
  • 将巨大的模式编译成Java

    有两个主要工具提供了将 XSD 模式编译为 Java 的方法 xmlbeans 和 JAXB 问题是 XSD 模式确实很大 30MB 的 XML 文件 大部分模式在我的项目中没有使用 所以我可以注释掉大部分代码 但这不是一个好的解决方案 目
  • 将非 Android 项目添加到 Android 项目

    我在 Eclipse 中有三个项目 Base Server 和 AndroidClient Base和Server是Java 1 7项目 而AndroidClient显然是一个android项目 基础项目具有在服务器和 Android 客户
  • 如何在 Spring 中使 @PropertyResource 优先于任何其他 application.properties ?

    我正在尝试在类路径之外添加外部配置属性资源 它应该覆盖任何现有的属性 但以下方法不起作用 SpringBootApplication PropertySource d app properties public class MyClass
  • 从jar中获取资源

    我有包含文件的 jar myJar res endingRule txt myJar wordcalculator merger Marge class 在 Marge java 中我有代码 private static final Str
  • 在Java中运行bat文件并等待

    您可能会认为从 Java 启动 bat 文件是一项简单的任务 但事实并非如此 我有一个 bat 文件 它对从文本文件读取的值循环执行一些 sql 命令 它或多或少是这样的 FOR F x in CD listOfThings txt do
  • 如何将 HTML 链接放入电子邮件正文中?

    我有一个可以发送邮件的应用程序 用 Java 实现 我想在邮件中放置一个 HTML 链接 但该链接显示为普通字母 而不是 HTML 链接 我怎样才能将 HTML 链接放入字符串中 我需要特殊字符吗 太感谢了 Update 大家好你们好 感谢
  • 使用 Elastic Beanstalk 进行 Logback

    我在使用 Elastic Beanstalk 记录应用程序日志时遇到问题 我正在 AWS Elastic Beanstalk 上的 Tomcat 8 5 with Corretto 11 running on 64bit Amazon Li
  • 如何在 Spring 3.1 中构造函数自动装配 HttpServletResponse?

    我有一个请求范围的 bean 并且需要访问 HttpServletResponse 和 HttpServletRequest 对象 我需要在构造函数中访问这些对象 因此属性自动装配不是一个选项 我做了以下事情 Component Scope
  • 不可变的最终变量应该始终是静态的吗? [复制]

    这个问题在这里已经有答案了 在java中 如果一个变量是不可变的并且是final的 那么它应该是一个静态类变量吗 我问这个问题是因为每次类的实例使用它时创建一个新对象似乎很浪费 因为无论如何它总是相同的 Example 每次调用方法时都会创
  • Spring Boot中ServletContext初始化后如何创建bean?

    我有一个 bean 它实现 ServletContextAware 和 BeanFactoryPostProcessor 接口 我需要在 ServletContext 完成初始化后将此 bean 注册到 applicationContext
  • 列表过滤器内的 Java 8 lambda 列表

    示例 JSON id 1 products id 333 status Active id 222 status Inactive id 111 status Active id 2 products id 6 status Active
  • Android View Canvas onDraw 未执行

    我目前正在开发一个自定义视图 它在画布上绘制一些图块 这些图块是从多个文件加载的 并将在需要时加载 它们将由 AsyncTask 加载 如果它们已经加载 它们只会被绘制在画布上 这工作正常 如果加载了这些图片 AsyncTask 就会触发v
  • Java/Python 中的快速 IPC/Socket 通信

    我的应用程序中需要两个进程 Java 和 Python 进行通信 我注意到套接字通信占用了 93 的运行时间 为什么通讯这么慢 我应该寻找套接字通信的替代方案还是可以使其更快 更新 我发现了一个简单的修复方法 由于某些未知原因 缓冲输出流似
  • Java 和/C++ 在多线程方面的差异

    我读过一些提示 多线程实现很大程度上取决于您正在使用的目标操作系统 操作系统最终提供了多线程能力 比如Linux有POSIX标准实现 而windows32有另一种方式 但我想知道编程语言水平的主要不同 C似乎为同步提供了更多选择 例如互斥锁

随机推荐

  • HTTP服务器实现(一)

    实现一个HTTP服务器就是实现一个程序可以接受客户端发送给服务器进程的请求消息 通过解析这些请求消息 做出相应的响应 下面我们先来梳理一下整体的思路 进行服务器的初始化 int init server char ip int port in
  • FPGA时序约束系列文章汇总

    时序约束在FPGA开发中起着非常关键的作用 与时序约束相关的方面包括时钟分析 路径分析 布线和布局优化等 时序约束的正确性和准确性对于设计的成功是至关重要的 因为它们对电路的时序性能 功耗和资源利用率有着重要影响 有效的时序约束可以帮助设计
  • UE4开发学习笔记(双人游戏共享视角,共享相机)

    先创建一个共享相机的actor类share camera 里面只要spring arm和camera就行 在关卡蓝图里设置摄像机位置 setviewtargetwithblend是将character本身的摄像机过渡到公共摄像机 这里的bl
  • 前端小白练习题查缺补漏2

    1 声明不是 HTML 标签 它是指示 web 浏览器关于页面使用哪个 HTML 版本进行编写的指令 声明没有结束标签 声明对大小写不敏感 2 end Math pow 2 50 111111 假设的值 var start end 100
  • duilib-自定义圆形按钮-环形进度条控件

    duilib 自定义圆形按钮 环形进度条控件 如何自定义一个圆形按钮控件内嵌到环形进度条底部 点击按钮刷新进度条值 类似下图 1 在UIDefine h中增加宏定义 define DUI CTR BTN PROGRESS T btnProg
  • sqli-labs(27)

    0X01 先查询闭合 id 1 报错 id 1 正确 知道是 的闭合语句 0X02那么开始我们的注入之旅 空格过滤了 尝试一下 0a绕过 也被过滤了 那么用and 1 1构造闭合 id 1 1 1 显示正确 我们来爆一下数据名称 哦豁 un
  • 产品经理工作积累(1)

    相比较做技术工作的人来说 做产品工作的更倾向于软能力 而这种软能力体现在个人的产品思想上 更或者说做产品的思维或理念 做产品除了本身的产品设计能力外 还有一点就是产品的思想 同一种产品不太的产品做出来后产品形态都会不同 特别是对于一些有独特
  • 在 Shell 脚本中调用另一个 Shell 脚本的三种方式

    先来说一下主要以下有几种方式 fork 如果脚本有执行权限的话 path to foo sh 如果没有 sh path to foo sh exec exec path to foo sh source source path to foo
  • android 反编译方法、工具介绍

    网上有很多的反编译文章 个人认为写的比较好的文章有 APK反编译得工具总结 转载 hayhx 博客园 我也是参考其文章来的 本人写此文章目的 以及反编译运用场景 主要有以下几方面 记录反编译的方法 方便自己用的时候比较方便 起到记录的作用
  • python词频统计_Python中文词频统计

    1 下载一长篇中文小说 2 从文件读取待分析文本 3 安装并使用jieba进行中文分词 pip install jieba import jieba ljieba lcut text import jieba txt open r piao
  • async 和 await

    async async是一个加在函数前面的修饰符 被async修饰的函数会默认返回一个promise对象 可以使用then方法添加回调函数 返回的promise对象的结果是由async函数执行的返回值的结果来决定的 1 当async函数内部
  • 一步步教你用 WebVR 实现虚拟现实游戏

    翻译 疯狂的技术宅 www smashingmagazine com 2018 11 vir 在本教程中 我们将创建三维对象并为它们添加简单的交互 此外 你还可以学到如何在客户端和服务器之间建立简单的消息传递系统 虚拟现实 VR 是一种依赖
  • 说说HashMap的扩容机制

    HashMap的扩容机制 HashMap的数据结构 HashMap几个重要的元素 HashMap的扩容过程 1 为什么扩容 2 什么时候进行扩容 3 怎么扩容 HashMap的数据结构 JDK1 8为例 如图 先知道三个概念 table 存
  • Vmware安装Ubuntu出现 unable to find a medium containing a live file system

    一 前言 由于未知的原因 使用Vmware安装Ubuntu的时候 总是遇到奇怪的问题 忘记截图了 大致是 unable to find a medium containing a live file system 找了几个帖子 参考1 参考
  • ajax 调用node,Node.js 远程调用 方法大全

    关于Node js 远程调用 远程调用 简称 RPC 主要是指服务器或集群之间对处理过程的调用 通过远程调用可以打通不同系统之间的数据与功能 或是抽离与建立公共的逻辑统一提供服务 远程调用的两端也称为远程调用的客户端与服务端 一般是多对多的
  • 借助模糊逻辑将文化算法与和谐搜索相结合进行学习——文化和谐学习算法(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 Matlab代码实现 4 参考文献 1 概述 文化和谐学习算法 创建于 18 Jan 2
  • 剑指 Offer 24. 反转链表

    定义一个函数 输入一个链表的头节点 反转该链表并输出反转后链表的头节点 示例 输入 1 gt 2 gt 3 gt 4 gt 5 gt NULL 输出 5 gt 4 gt 3 gt 2 gt 1 gt NULL 代码 Definition f
  • exchange 系统管理器 服务器,在“exchange系统管理器”安全里有个receive as是什么权限?谢谢...

    您好 用Visual Basic访问Microsoft Exchange和Outlook的数据 想通过Access中的Visual Basic for Applications VBA 和数据访问对象 DAO 的方法和对象来连接和导入来自E
  • 故事板(Storyboard)

    1 使用Storyboard完成各项常见功能 1 1 问题 故事板Storyboard是IOS5开始引入的一个新的系统 将多个视图文件 类似xib文件 集中到一个单独的可视化工作区间 负责创建和管理所有的界面及界面间的跳转 每一个Story
  • 【Log日志】springboot项目中集成Log日志详解

    springboot项目中集成Log日志详解 一 Log日志介绍 1 Log 日志组件主要作用及用途 2 日志的级别Level 级别控制 3 日志的输出Import 3 1 快速使用 3 2 日志文件输出 3 3 自定义配置 4 Sprin