关于Profile配置文件
在Spring系列框架中,关于配置文件,允许同时存在多个配置文件(例如同时存在a.yml
、b.yml
等),并且,你可以按需切换某个配置文件,这些默认不生效、需要被激活才生效的配置,称之为Profile配置。
在Spring Boot项目中,Profile配置的文件名必须是application-自定义名称.properties
(或使用YAML的扩展名),例如:application-a.yml
、application-b.yml
,并且,这类配置文件默认就是没有激活的。
通常,关于“自定义名称”部分的惯用名称有:
dev
:表示开发环境test
:表示测试环境prod
:表示生产环境(项目上线)
当然,你也可以根据你所需要的环境或其它特征来处理“自定义名称”部分。
在Spring Boot项目中,application.properties
(或使用YAML的扩展名)是始终加载的配置文件,当需要激活某个Profiel配置文件时,可以在application.properties
中配置:
spring.profiles.active=自定义名称
例如:
在开发实践中,需要学会区分哪些配置属性是固定的,哪些是可能调整的,然后,把不会因为环境等因素而发生变化的配置写在application.properties
中去,把可能调整的配置写在Profile文件中。
例如,在application.yml
中配置(以下配置中不包含连接数据库的URL、用户名、密码):
spring:
profiles:
active: dev
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
initial-size: 5
max-active: 10
mybatis:
mapper-locations: classpath:mapper/*.xml
knife4j:
enable: true
并且,在其它Profile配置中补充可能调整的配置,例如在application-dev.yml
中配置:
spring:
datasource:
url: jdbc:mysql://localhost:3306/mall_pms?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
username: root
password: root
另外,通过spring.profiles.active
激活配置时,此属性的值可以使用逗号分隔来激活多个配置,例如:
spring.profiles.active=dev,test
如果同时激活的配置中,有相同的属性,但属性值并不同,以偏后的Profile配置文件中的配置值为准,按照以上代码,则以test
中的配置为准!
另外,所有Profile配置的优先级都高于application.properties
。
关于Slf4j日志
在开发实践中,应该将数据的关键变化、关联的处理流程记录下来,以便于出现问题时可以辅助排查问题!
注意:在开发实践中,禁止使用System.out.println()
的做法输出内容(测试代码除外),主要原因有:
- 不易于编写代码
- 如果输出的结果中存在较多的字符串与变量的拼写,代码的可读性非常差
- 执行效率非常低下
- 字符串的拼接效率非常低
- 无论什么情况下都会显示
- 也许某些输出的数据是敏感的,在开发过程中输出这些数据是为了便于调试,但是,在生产过程中不应该被看到
应该使用日志框架,通过输出日志的方式,来记录相关信息!
在Spring Boot框架的基础依赖项(spring-boot-starter
)中已经包含日志框架的依赖项, 所以,并不需要专门的去添加日志框架的依赖项,是可以直接使用的!
在添加了Lombok依赖项后,可以在任何类上添加@Slf4j
注解,则Lombok会在编译期自动在此类中声明名为log
的变量,通过此变量调用方法即可输出日志。
日志是有显示级别的,根据日志内容的重要程度,从可以不关注,到必须关注,依次为:
trace
:跟踪信息,例如记录程序执行到了哪个环节,或哪个类、哪个方法等debug
:调试信息,通常输出了一些数据值,用于观察数据的走向、变化过程info
:一般信息,通常不涉及隐私或机密,即使被他人看到也不要紧的warn
:警告信息,通常是可能存在某种问题,但却不影响程序的执行error
:错误信息
在使用log
变量输出日志时,可以调用以上5个级别对应的方法,即可输出对应级别的日志!例如调用log.info()
方法输出的就是info
级别的日志,调用log.error()
方法输出的就是error
级别的日志。
在日志框架中,输出每个级别的方法的参数列表都有相同的版本,例如存在:
void info(String message);
void info(String message, Object... args);
就还有:
void trace(String message);
void trace(String message, Object... args);
void debug(String message);
void debug(String message, Object... args);
void warn(String message);
void warn(String message, Object... args);
void error(String message);
void error(String message, Object... args);
在普通项目中,默认显示debug
级别的日志,则debug
级别及更加重要级别的日志都会显示出来,即trace
级别不会被显示!
在Spring Boot项目中,默认显示info
级别的日志!
在Spring Boot项目中,可以通过配置文件中的logging.level.根包名[.类名]
属性来调整日志的显示级别!
提示:以上
logging.level.根包名[.类名]
中的中括号部分是可选的!
例如配置为:
logging:
level:
cn.tedu.csmall.product: trace
则cn.tedu.csmall.product
包及其子孙包下所有的类中输出的日志的显示级别都将是trace
!
在输出日志时,如果需要输出一些变量的值,应该优先使用参数列表为(String message, Object... args)
的方法,例如:
int x = 1;
int y = 2;
log.info("x = {}, y = {}, x + y = {}", x, y, x + y);
需要注意:SLF4j日志框架只是一个日志标准,并没有具体的实现日志功能,而具体的功能是由logback
、log4j
等日志框架实现的。
SLF4j日志框架有一个接口Logger接口,定义了有这些方法,但是这些方法它没有自己实现,它是调用了log4j来实现的,这样做的好处是它约定了日志框架的API,有什么方法,有什么参数列表,如果后面log4j不好用,那就再换调用其他的框架,但是我们已经写好的代码不用变,因为
SLF4j日志的API没有变。和接口编程是差不多的一个道理。
如果要问,SLF4j和log4j的区别,一个是标准,一个是实现了具体的功能,然后这个标准包含了接口,接口调用了log4j里面的方法来实现的。