[Java EE] Spring 配置 和 日志

目录

[1. 配置文件](#1. 配置文件)

[1.1 作用](#1.1 作用)

[1.2 Spring Boot 配置文件](#1.2 Spring Boot 配置文件)

[1.3 读取配置文件](#1.3 读取配置文件)

[1.3.1 配置对象](#1.3.1 配置对象)

[1.3.2 配置集合](#1.3.2 配置集合)

[1.3.3 配置Map](#1.3.3 配置Map)

[1.4 yml 优缺点](#1.4 yml 优缺点)

[2. 日志](#2. 日志)

[2.1 日志的作用](#2.1 日志的作用)

[2.2 日志的使用](#2.2 日志的使用)

[2.3 日志框架](#2.3 日志框架)

[2.3.1 门面模式(外观模式)](#2.3.1 门面模式(外观模式))

[2.4 SLF4J 框架介绍](#2.4 SLF4J 框架介绍)

[2.5 日志格式的说明](#2.5 日志格式的说明)

[2.5.1 日志级别](#2.5.1 日志级别)

[2.5.3 日志级别的使用](#2.5.3 日志级别的使用)

[2.5.4 日志配置](#2.5.4 日志配置)

[2.5.5 日志持久化](#2.5.5 日志持久化)

[2.5.6 配置日志文件分割](#2.5.6 配置日志文件分割)

[2.5.7 配置日志格式](#2.5.7 配置日志格式)

[2.5.8 简单的日志输出](#2.5.8 简单的日志输出)


1. 配置文件

1.1 作用

主要是为了解决硬编码带来的问题, 把可能会发生改变的信息集中在一个地方, 当我们启动某个程序时, 应用程序从配置文件中读取数据, 并加载运行。使用配置文件, 可以使程序完成用户和应用程序的交互, 或者应用程序与其他应用程序的交互。

1.2 Spring Boot 配置文件

Spring Boot 支持并且定义了配置文件的格式, 很多项目或者框架的配置信息放在其中, 比如项目的启动端口、数据库的连接信息、第三方系统的调用密钥等信息、用于发现和定位问题的日志等。

Spring Boot 配置文件格式

大致有以下两种:

(1) application.properties

properties 配置是以 key-value 的形式配置的,key 和 value 之间使用"="连接, 每次使用都需要写前缀,会有很多的冗余的信息,当表示纯字符串的时候需要加 ' ' 单双引号。

java 复制代码
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/testdbcharacterEncoding=utf8&useSSL=false
spring.datasource.username=root
spring.datasource.password='123456'

(2) application.yml

yml 是 YAML 的缩写, 全称为 Yet Another Markup Language , yml 是树形结构的配置文件, 它的基础语法是"key: value"。key 和 value 之间使用英文冒号加空格的方式组成 ,空格不能省略

使用 yml 连接数据库:

java 复制代码
spring:
  datasource:
  url: jdbc:mysql://127.0.0.0:3306/dbname?characterEncoding=utf8&useSSL=false
  username: root
  password: root

1.3 读取配置文件

yml 和 properties 都是用 org 里的 @Value "${}" 格式读取, 如下代码所示

java 复制代码
mykey.key1 = Miraitowa
java 复制代码
package com.huangyi.test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class Controller {
    @Value("${mykey.key1}")
    private  String key1;
    @RequestMapping("/key")
    public String key() {
        return key1;
    }
}

运行结果:

1.3.1 配置对象

我们可以在 yml 中配置对象

java 复制代码
student:
  id: 1
  name: Java
  age: 18

这个时候我们读取对象 需要使用 @ConfigurationProperties 来读取, 代码如下

java 复制代码
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@ConfigurationProperties(prefix = "student")
@Component
@Data
public class Student {
    private int id;
    private String name;
    private int age;
}

调用类如下代码:

java 复制代码
@RestController
public class StudentController {
    @Autowired
    private Student student;
    @RequestMapping("/readStudent")
    public String readStudent(){
        return student.toString();
    }
}

访问结果如下:

1.3.2 配置集合

配置文件也可以配置 list 集合, 如下所示:

java 复制代码
  dbtypes:
    name:
      - mysql
      - sqlserver
      - db2

我们也使用 @ConfigurationProperties(prefix = "xxxxx") 来读取集合

java 复制代码
@Component
@ConfigurationProperties("dbtypes")
@Data
public class ListConfig {
    private List<String> name;
}

访问集合的实现如下:

java 复制代码
@RestController
public class ReadYml2 {
    @Autowired
    private ListConfig listConfig;
    @RequestMapping("/readList")
    public String readList(){
        return listConfig.toString();
    }
}
1.3.3 配置Map
java 复制代码
maptypes:
 map:
 k1: kk1
 k2: kk2
 k3: kk3

Map 的读取也是使用 @ConfigurationProperties(prefix = "xxxxx") 来读取

java 复制代码
@Component
@ConfigurationProperties("maptypes")
@Data
public class MapConfig {
    private HashMap<String,String> map;
}

打印类的实现如下

java 复制代码
@RestController
public class ReadYml2 {
    @Autowired
    private MapConfig mapConfig;
    @RequestMapping("/readMap")
    public String readStudent(){
        return mapConfig.toString();
    }
}

1.4 yml 优缺点

优点:

(1) 可读性高, 写法简单, 易于理解

(2) 支持更多的数据类型, 可以简单表达对象, 数组, List, Map等数据形态

缺点:

(1) 不适合写复杂的配置文件

2. 日志

2.1 日志的作用

随着项目的复杂提升, 我们需要借助日志定位排查问题。当需要记录一些用户的操作记录时, 也可以使用日志来记录用户的一些喜好,日志主要是为了发现问题, 分析问题, 定位问题。

2.2 日志的使用

(1) 在程序中得到日志对象

java 复制代码
private static Logger logger = LoggerFactory.getLogger(LoggerController.class);

LoggerFactory.getLogger 需要一个参数, 标识这个日志的名称, 这样就可以知道是哪个类输出的日志, 方便定位到问题类。

Logger 对象是属于 org.slf4j 包下的, 不要导⼊错包。

(2) 使用日志对象输出要打印的内容

java 复制代码
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class LoggerController {
    private static Logger logger =
            LoggerFactory.getLogger(LoggerController.class);
    @RequestMapping("/logger")
    public String logger(){
        logger.info("--------------要输出⽇志的内容----------------");
        return "打印⽇志";
    }
}

打印日志效果展示:

2.3 日志框架

SLF4J 不同于其他日志框架, 它不是一个真正的日志实现,而是一个抽象层,对日志框架制定的一种规范标准,所有的SLF4J 不能独立使用,需要和具体的日志框架配合使用

2.3.1 门面模式(外观模式)

门面模式又称为外观模式, 提供了一个统一的接口, 用来访问子系统中的一群接口, 其主要特征是定义了一个高层接口, 让子系统更容易使用。

门面模式主要包含两种角色

1.外观角色(Facade):也称为门面角色, 系统对外的统一接口。

2.子系统角色(SubSystem): 可以同时有一个或多个 SubSystem, 每一个都不是一个单独的类,而是一个类的集合。SubSystem 不知道 Facade 的存在, 对于SubSystem 而言, Facade 只是另一个客户端(Facade 对 SubSystem 透明)

门面模式的优点

  1. 减少了系统的相互依赖,实现了客户端与子系统解耦合

  2. 提高了灵活性,简化了客户端对子系统的使用难度

  3. 提高了安全性,可以灵活设定访问权限

2.4 SLF4J 框架介绍

SLF4J 是其他日志框架的门面,可以理解是提供日志服务的统一API接口,并不涉及到具体的日志逻辑实现,常见的日志框架有 log4J,logback 等,如果一个项目使用了 log4j,而你依赖的另一类库依赖于另外一个日志框架 logback, 那么你就需要把 logback 也加载进去,

存在问题:

  1. 不同日志框架的 API 接口和配置文件不同,如果多个人日志框架共存,那么不得不维护多套配置文件

  2. 如果要更换日志框架,就需要修改代码,过程中可能就会存在代码冲突

  3. 如果引入的第三方框架使用了多套,那么就不得不维护多套配置

2.5 日志格式的说明

(1) 时间日期:精确到毫秒

(2) 日志级别:ERROR,WARN,INFO,DEBUG 或 TRACE

(3) 进程ID

(4) 线程名

(5) Logger名(通常使用源代码的类名)

(6) 日志内容

2.5.1 日志级别

日志级别代表着日志信息对应问题的严重性,为了更快的筛选符合目标的日志信息

• FATAL: 致命信息, 标识需要理解被处理的系统级错误

• ERROR: 错误信息, 级别较高的错误日志信息, 但仍然不影响系统的继续运行

• WARN: 警告信息, 不影响使用, 但需要注意的问题

• INFO: 普通信息, 用于记录应用程序正常运行时的一些信息

• DEBUG: 调试信息, 需要调试时候的关键信息打印

• TRACE: 追踪信息

日志的级别顺序

2.5.3 日志级别的使用

日志级别是开发人员自己设置的, 开发人员根据自己的理解来判断信息的重要程度

java 复制代码
    @RequestMapping("/printLog")
    public String printLog() {
        logger.trace("================= trace ===============");
        logger.debug("================= debug ===============");
        logger.info("================= info ===============");
        logger.warn("================= warn ===============");
        logger.error("================= error ===============");
        return "打印不同级别的⽇志" ;
    }

观察打印的日志结果:

结果发现, 只打印了INFO, WARN 和 ERROR 级别的日志

这与日志级别的配置有关, 日志的输出级别默认是 INFO 级别, 所以只会打印大于此级别的日志,

2.5.4 日志配置

日志级别配置只需要在配置文件中设置"logging.level"配置项即可

Properties 配置

java 复制代码
logging.level.root=debug

重新运行上述代码, 观察结果:

2.5.5 日志持久化

以上的日志都是在控制台输出, 但是我们需要把日志保存下来以便追溯问题, 把日志保存下来就叫持久化

日志持久化有两种方式:

  1. 配置日志文件名

  2. 配置日志的存储目录

yml配置:

java 复制代码
# 设置⽇志⽂件的⽂件名 
logging:
 file:
  name: logger/springboot.log
  path: D:/temp

运行程序, 该程序下多出一个日志文件: springboot.log

注意:logging.file.name 和 logging.file.path 两个配置的情况下, 只生效 logging.file.name 为准

2.5.6 配置日志文件分割

如果我们的日志都放在一个文件中, 随着项目的运行, 日志文件会越来越大, 需要对日志文件进行分割。

Properties 配置

java 复制代码
logging.logback.rollingpolicy.file-name-pattern=${LOG_FILE}.%d{yyyy-MM-dd}.%i
logging.logback.rollingpolicy.max-file-size=1KB

项目运行, 多打印一些日志, 分割结果如下:

2.5.7 配置日志格式
java 复制代码
logging.pattern.console='%d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %L [%thread] %m%n'

• %clr(表达式){颜色} 设置输入日志的颜色

• %d{} 日期和时间

• %5p 显示日志级别

• %t 线程名, %c 类的全限定名, %M method, %L 为行号, %thread 线程名称. %m 或者 %msg 显示输出消息, %n 换行符

2.5.8 简单的日志输出

每次使用 LoggerFactory.getLogger(xxxx.class) 很繁琐, 且每个类都添加一遍, lombok 给我们提供了一种更简单的方式

(1) 添加 lombok 框架支持

java 复制代码
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>

(2) 使用 @slf4j 注解输出日志

java 复制代码
package com.huangyi.test;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
public class LogController {
    public void log(){
        log.info("--------------要输出⽇志的内容----------------");
    }
}

lombok 提供的 slf4j 会帮我们提供一个日志对象 log, 我门直接使用就可以

==============================================================================

如果觉得有帮助的话给博主点个赞吧!祝您在学习的路上顺风顺水!

相关推荐
佩奇的技术笔记2 小时前
Java学习手册:Web 应用架构概述
java
SuperherRo4 小时前
Web开发-JavaEE应用&原生和FastJson反序列化&URLDNS链&JDBC链&Gadget手搓
java·java-ee·jdbc·fastjson·反序列化·urldns
xxjiaz5 小时前
二分查找-LeetCode
java·数据结构·算法·leetcode
nofaluse6 小时前
JavaWeb开发——文件上传
java·spring boot
爱的叹息6 小时前
【java实现+4种变体完整例子】排序算法中【插入排序】的详细解析,包含基础实现、常见变体的完整代码示例,以及各变体的对比表格
java·算法·排序算法
爱的叹息7 小时前
【java实现+4种变体完整例子】排序算法中【快速排序】的详细解析,包含基础实现、常见变体的完整代码示例,以及各变体的对比表格
java·算法·排序算法
6v6-博客7 小时前
2024年网站开发语言选择指南:PHP/Java/Node.js/Python如何选型?
java·开发语言·php
Miraitowa_cheems7 小时前
[Java EE] Spring AOP 和 事务
java·java-ee·aop·spring 事务
光头小小强0077 小时前
致远OA——自定义开发rest接口
java·经验分享·spring·tomcat