springboot入門之路(三)_Spring Boot特性
4.Spring Boot特性
閱讀:springboot入門之路(二)
spring Boot特性:代碼獲取點(diǎn)我
4.1 自定義Banner
- 接下來我們就來介紹一下這個(gè)輕松愉快的自定義banner功能。實(shí)現(xiàn)的方式非常簡單,我們只需要在Spring Boot工程的/src/main/resources目錄下創(chuàng)建一個(gè)banner.txt文件,然后將ASCII字符畫復(fù)制進(jìn)去澡匪,就能替換默認(rèn)的banner了。比如上圖中的輸出,就采用了下面的banner.txt內(nèi)容
${AnsiColor.BRIGHT_GREEN}
## ## ### ######## ######## ## ## ## ## ######## ## ## ## ## ######## ### ########
## ## ## ## ## ## ## ## ## ## ### ## ## ## ## ## ## ## ## ## ## ## ##
## ## ## ## ## ## ## ## #### #### ## ## ## ## ## #### ## ## ## ## ##
######### ## ## ######## ######## ## ## ## ## ###### ## ## ## ## ###### ## ## ########
## ## ######### ## ## ## ## #### ## ## ## ## ## ## ######### ## ##
## ## ## ## ## ## ## ## ### ## ## ## ## ## ## ## ## ## ##
## ## ## ## ## ## ## ## ## ######## ### ### ## ######## ## ## ## ##
${AnsiColor.BRIGHT_RED}
Application Version: ${application.version}${application.formatted-version}
Spring Boot Version: ${spring-boot.version}${spring-boot.formatted-version}
- 注:如果想以編程的方式產(chǎn)生一個(gè)banner凌那,可以使用SpringBootApplication.setBanner(…)方法。使用
org.springframework.boot.Banner接口吟逝,實(shí)現(xiàn)你自己的printBanner()方法帽蝶。
4.2 命令行啟動(dòng)器
- 如果你想獲取原始的命令行參數(shù),或一旦SpringApplication啟動(dòng),你需要運(yùn)行一些特定的代碼励稳,你可以實(shí)現(xiàn)
CommandLineRunner接口佃乘。在所有實(shí)現(xiàn)該接口的Spring beans上將調(diào)用run(String… args)方法。
package com.test.common;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
/**
* 類CommonConfig.java的實(shí)現(xiàn)描述:TODO 類實(shí)現(xiàn)描述
*
* @author tangjinhui 2018年4月9日 下午4:15:13
*/
@Component
public class CommonConfig implements CommandLineRunner {
@Override
public void run(String... arg0) throws Exception {
// TODO Auto-generated method stub
System.err.print("commandLineRunner");
}
}
- 如果一些CommandLineRunner beans被定義必須以特定的次序調(diào)用驹尼,你可以額外實(shí)現(xiàn)org.springframework.core.Ordered接
口或使用org.springframework.core.annotation.Order注解趣避。
4.3.1 外化配置
- Spring Boot允許外化(externalize)你的配置,這樣你能夠在不同的環(huán)境下使用相同的代碼新翎。你可以使用properties文件程帕,
YAML文件,環(huán)境變量和命令行參數(shù)來外化配置地啰。使用@Value注解愁拭,可以直接將屬性值注入到你的beans中,并通過Spring
的Environment抽象或綁定到結(jié)構(gòu)化對象來訪問亏吝。
- 需要以下面的次序考慮屬性:
- 命令行參數(shù)
- 來自于java:comp/env的JNDI屬性
- Java系統(tǒng)屬性(System.getProperties())
- 操作系統(tǒng)環(huán)境變量
- 只有在random.*里包含的屬性會(huì)產(chǎn)生一個(gè)RandomValuePropertySource
- 在打包的jar外的應(yīng)用程序配置文件(application.properties岭埠,包含YAML和profile變量)
- 在打包的jar內(nèi)的應(yīng)用程序配置文件(application.properties,包含YAML和profile變量)
- 在@Configuration類上的@PropertySource注解
- 默認(rèn)屬性(使用SpringApplication.setDefaultProperties指定)
4.3.2 屬性占位符
- 當(dāng)application.properties里的值被使用時(shí)蔚鸥,它們會(huì)被存在的Environment過濾惜论,所以你能夠引用先前定義的值(比如,系統(tǒng)屬
-性)止喷。
app.name=MyApp
app.description=${app.name} is a Spring Boot application
4.3.3 使用YAML代替Properties
- YAML是JSON的一個(gè)超集馆类,也是一種方便的定義層次配置數(shù)據(jù)的格式。無論你何時(shí)將SnakeYAML 庫放到classpath下启盛,
SpringApplication類都會(huì)自動(dòng)支持YAML作為properties的替換蹦掐。 - Spring框架提供兩個(gè)便利的類用于加載YAML文檔,YamlPropertiesFactoryBean會(huì)將YAML作為Properties來加載僵闯,
YamlMapFactoryBean會(huì)將YAML作為Map來加載卧抗。
示例:
environments:
dev:
url: http://dev.bar.com
name: Developer Setup
prod:
url: http://foo.bar.com
name: My Cool App
上面的YAML文檔會(huì)被轉(zhuǎn)化到下面的屬性中:
environments.dev.url=http://dev.bar.com
environments.dev.name=Developer Setup
environments.prod.url=http://foo.bar.com
environments.prod.name=My Cool App
YAML列表被表示成使用[index]間接引用作為屬性keys的形式,例如下面的YAML:
my:
servers:
- dev.bar.com
- foo.bar.com
將會(huì)轉(zhuǎn)化到下面的屬性中:
my.servers[0]=dev.bar.com
my.servers[1]=foo.bar.com
使用Spring DataBinder工具綁定那樣的屬性(這是@ConfigurationProperties做的事)鳖粟,你需要確定目標(biāo)bean中有個(gè)
java.util.List或Set類型的屬性社裆,并且需要提供一個(gè)setter或使用可變的值初始化它,比如向图,下面的代碼將綁定上面的屬性:
@ConfigurationProperties(prefix="my")
public class Config {
private List<String> servers = new ArrayList<String>();
public List<String> getServers() {
return this.servers;
}
4.3.4 YAML缺點(diǎn)
- YAML文件不能通過@PropertySource注解加載泳秀。所以,在這種情況下榄攀,如果需要使用@PropertySource注解的方式加載值嗜傅,
那就要使用properties文件。
4.3.5 安全的配置屬性
- 使用@Value("${property}")注解注入配置屬性有時(shí)可能比較笨重檩赢,特別是需要使用多個(gè)properties或你的數(shù)據(jù)本身有層次結(jié)
構(gòu)吕嘀。為了控制和校驗(yàn)?zāi)愕膽?yīng)用配置,Spring Boot提供一個(gè)允許強(qiáng)類型beans的替代方法來使用properties。
示例:
@Component
@ConfigurationProperties(prefix="connection")
public class ConnectionSettings {
private String username;
private InetAddress remoteAddress;
// ... getters and setters
}
- 當(dāng)@EnableConfigurationProperties注解應(yīng)用到你的@Configuration時(shí)偶房,任何被@ConfigurationProperties注解的beans將自
動(dòng)被Environment屬性配置趁曼。這種風(fēng)格的配置特別適合與SpringApplication的外部YAML配置進(jìn)行配合使用。
# application.yml
connection:
username: admin
remoteAddress: 192.168.1.1
# additional configuration as required
為了使用@ConfigurationProperties beans棕洋,你可以使用與其他任何bean相同的方式注入它們挡闰。
4.3.6 Profiles
- Spring Profiles提供了一種隔離應(yīng)用程序配置的方式,并讓這些配置只能在特定的環(huán)境下生效掰盘。任何@Component或
@Configuration都能被@Profile標(biāo)記摄悯,從而限制加載它的時(shí)機(jī)。
舉例子:
@Configuration
@Profile("production")
public class ProductionConfiguration {
// ...
}
- 以正常的Spring方式庆杜,你可以使用一個(gè)spring.profiles.active的Environment屬性來指定哪個(gè)配置生效射众。你可以使用平常的任
何方式來指定該屬性碟摆,例如晃财,可以將它包含到你的application.properties中:
spring.profiles.active=dev,hsqldb
4.3.6.1 添加激活的配置(profiles)
- spring.profiles.active屬性和其他屬性一樣都遵循相同的排列規(guī)則,最高的PropertySource獲勝鼎天。也就是說阅羹,你可以在
application.properties中指定生效的配置苗沧,然后使用命令行開關(guān)替換它們。
有時(shí)钢猛,將特定的配置屬性添加到生效的配置中而不是替換它們是有用的。 - spring.profiles.include屬性可以用來無條件的添加
生效的配置轩缤。SpringApplication的入口點(diǎn)也提供了一個(gè)用于設(shè)置額外配置的Java API(比如命迈,在那些通過 - spring.profiles.active屬性生效的配置之上):參考setAdditionalProfiles()方法。
示例:當(dāng)一個(gè)應(yīng)用使用下面的屬性火的,并用 --spring.profiles.active=prod 開關(guān)運(yùn)行壶愤,那proddb和prodmq配置也會(huì)生效:
在yaml中配置:
spring.profiles: prod
spring.profiles.include: proddb,prodmq
4.3.6.2 Profile特定配置文件
-
application.properties(或application.yml)和通過@ConfigurationProperties引用的文件這兩種配置特定變種都被當(dāng)作文件
來加載的
4.4 日志的配置使用
- Spring Boot內(nèi)部日志系統(tǒng)使用的是Commons Logging,但開放底層的日志實(shí)現(xiàn)馏鹤。默認(rèn)為會(huì)Java Util Logging, Log4J, Log4J2
和Logback提供配置征椒。每種情況下都會(huì)預(yù)先配置使用控制臺(tái)輸出,也可以使用可選的文件輸出湃累。
默認(rèn)情況下勃救,如果你使用'Starter POMs',那么就會(huì)使用Logback記錄日志治力。為了確保那些使用Java Util Logging, Commons
Logging, Log4J或SLF4J的依賴庫能夠正常工作蒙秒,正確的Logback路由也被包含進(jìn)來。
注:如果上面的列表看起來令人困惑宵统,不要擔(dān)心晕讲,Java有很多可用的日志框架。通常,你不需要改變?nèi)罩疽蕾囈嫘郑琒pring Boot
默認(rèn)的就能很好的工作锻梳。-
4.4.1 日志格式
Spring Boot默認(rèn)的日志輸出格式如下:
2018-04-10 16:38:35.165 INFO 9224 --- [ restartedMain] com.test.SpringbootApplication : Starting SpringbootApplication on PC-20170526TZZP with PID 9224 (started by Administrator in E:\ruiyouProjects\springbootDemo(三))
2018-04-10 16:38:35.187 INFO 9224 --- [ restartedMain] com.test.SpringbootApplication : No active profile set, falling back to default profiles: default
2018-04-10 16:38:37.059 INFO 9224 --- [ restartedMain] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@193b4fef: startup date [Tue Apr 10 16:38:37 CST 2018]; root of context hierarchy
輸出的節(jié)點(diǎn)(items)如下:
- 日期和時(shí)間 - 精確到毫秒,且易于排序净捅。
- 日志級別 - ERROR, WARN, INFO, DEBUG 或 TRACE疑枯。
- Process ID。
- 一個(gè)用于區(qū)分實(shí)際日志信息開頭的---分隔符蛔六。
- 線程名 - 包括在方括號中(控制臺(tái)輸出可能會(huì)被截?cái)啵?/li>
- 日志名 - 通常是源class的類名(縮寫)荆永。
- 日志信息。
8
4.4.2 日志級別
- 所有支持的日志系統(tǒng)在Spring的Environment(例如在application.properties里)都有通
logging.level:日志級別控制前綴国章,*為包名或Logger名
LEVEL:選項(xiàng)TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF具钥。
示例:application.properties
logging.level.root=WARN:root日志以WARN級別輸出
logging.level.org.springframework.web: DEBUG #包下所有class以DEBUG級別輸出
2018-04-10 17:20:08.942 INFO 9224 --- [ restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729
2018-04-10 17:20:09.010 INFO 9224 --- [ restartedMain] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2018-04-10 17:20:09.020 DEBUG 9224 --- [ restartedMain] o.s.w.s.resource.ResourceUrlProvider : Looking for resource handler mappings
2018-04-10 17:20:09.027 DEBUG 9224 --- [ restartedMain] o.s.w.s.resource.ResourceUrlProvider : Found resource handler mapping: URL pattern="/**/favicon.ico", locations=[ServletContext resource [/], class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/], class path resource []], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver@3bd57b15]
4.4.3 日志文件輸出路徑配置
- 默認(rèn)情況下,Spring Boot將日志輸出到控制臺(tái)液兽,不會(huì)寫到日志文件骂删。
- 使用Spring Boot喜歡在application.properties或application.yml配置,這樣只能配置簡單的場景四啰,保存路徑宁玫、日志格式等,復(fù)雜的場景(區(qū)分 info 和 error 的日志柑晒、每天產(chǎn)生一個(gè)日志文件等)滿足不了欧瘪,只能自定義配置,下面會(huì)演示匙赞。
如果要編寫除控制臺(tái)輸出之外的日志文件佛掖,則需在application.properties中設(shè)置logging.file或logging.path屬性。logging.file涌庭,設(shè)置文件芥被,可以是絕對路徑,也可以是相對路徑脾猛。如:logging.file=my.log
logging.path撕彤,設(shè)置目錄,會(huì)在該目錄下創(chuàng)建spring.log文件猛拴,并寫入日志內(nèi)容羹铅,如:logging.path=/var/log
如果只配置 logging.file,會(huì)在項(xiàng)目的當(dāng)前路徑下生成一個(gè) xxx.log 日志文件愉昆。
如果只配置 logging.path职员,在 /var/log文件夾生成一個(gè)日志文件為 spring.log
#默認(rèn)會(huì)在設(shè)置的 path 生成一個(gè)spring.log 文件。
#logging.path:E:/log1234
logging.pattern.console:"%d - %msg%n"
logging.file:E:/log1234/springboot_log_4.log
注:二者不能同時(shí)使用跛溉,如若同時(shí)使用焊切,則只有l(wèi)ogging.file生效
默認(rèn)情況下扮授,日志文件的大小達(dá)到10MB時(shí)會(huì)切分一次,產(chǎn)生新的日志文件专肪,默認(rèn)級別為:ERROR刹勃、WARN、INFO
4.4.4 自定義日志配置
4.4.4.1 日志系統(tǒng)定制
通過將適當(dāng)?shù)膸焯砑拥絚lasspath嚎尤,可以激活各種日志系統(tǒng)荔仁。然后在classpath的根目錄(root)或通過Spring Environment
的 logging.config 屬性指定的位置提供一個(gè)合適的配置文件來達(dá)到進(jìn)一步的定制(注意由于日志是在ApplicationContext被創(chuàng)
建之前初始化的,所以不可能在Spring的@Configuration文件中芽死,通過@PropertySources控制日志乏梁。系統(tǒng)屬性和平常的
Spring Boot外部配置文件能正常工作)。-
日志系統(tǒng)定制
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
4.4.4.2日志系統(tǒng)定制路徑配置
Spring Boot官方推薦優(yōu)先使用帶有-spring的文件名作為你的日志配置(如使用logback-spring.xml关贵,而不是logback.xml)遇骑,命名為logback-spring.xml的日志配置文件,spring boot可以為它添加一些spring boot特有的配置項(xiàng)(下面會(huì)提到)揖曾。
默認(rèn)的命名規(guī)則落萎,并且放在 src/main/resources 下面即可:
如果你即想完全掌控日志配置,但又不想用logback.xml作為Logback配置的名字翩肌,application.yml可以通過logging.config屬性指定自定義的名字
logging.config=classpath:logging-config.xml
注:為了幫助定制一些其他的屬性模暗,從Spring的Envrionment轉(zhuǎn)換到系統(tǒng)屬性:
SpringEnvironment SystemProperty 評價(jià)
logging.file LOG_FILE 如果定義,在默認(rèn)的日志配置中使用
logging.path LOG_PATH 如果定義念祭,在默認(rèn)的日志配置中使用
PID PID 當(dāng)前的處理進(jìn)程(process)ID(如果能夠被發(fā)現(xiàn)且還沒有作為操作系統(tǒng)環(huán)境
變量被定義)
所有支持的日志系統(tǒng)在解析它們的配置文件時(shí)都能查詢系統(tǒng)屬性。具體可以參考spring-boot.jar中的默認(rèn)配置碍侦。
3. logback日志的配置詳解(springbootDemo(四)中查看該部分代碼)
3.1 根節(jié)點(diǎn)包含的屬性
scan:當(dāng)此屬性設(shè)置為true時(shí)粱坤,配置文件如果發(fā)生改變,將會(huì)被重新加載瓷产,默認(rèn)值為true站玄。
scanPeriod:設(shè)置監(jiān)測配置文件是否有修改的時(shí)間間隔,如果沒有給出時(shí)間單位濒旦,默認(rèn)單位是毫秒株旷。當(dāng)scan為true時(shí),此屬性生效尔邓。默認(rèn)的時(shí)間間隔為1分鐘晾剖。
debug:當(dāng)此屬性設(shè)置為true時(shí),將打印出logback內(nèi)部日志信息梯嗽,實(shí)時(shí)查看logback運(yùn)行狀態(tài)齿尽。默認(rèn)值為false。
根節(jié)點(diǎn)<configuration>有5個(gè)子節(jié)點(diǎn)灯节,下面一一會(huì)詳細(xì)介紹
子節(jié)點(diǎn)一 <root>
Root節(jié)點(diǎn)是必選節(jié)點(diǎn)循头,用來指定最基礎(chǔ)的日志輸出級別绵估,只有一個(gè)level屬性。
level:用來設(shè)置打印級別卡骂,大小寫無關(guān):TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF国裳,不能設(shè)置為INHERITED或者同義詞NULL。
默認(rèn)是DEBUG全跨。
可以包含零個(gè)或多個(gè)元素躏救,標(biāo)識這個(gè)appender將會(huì)添加到這個(gè)loger。
<root level="debug">
<appender-ref ref="console" />
<appender-ref ref="file" />
</root>
子節(jié)點(diǎn)二:<contextName> 設(shè)置上下文名稱
每個(gè)logger都關(guān)聯(lián)到logger上下文螟蒸,默認(rèn)上下文名稱為“default”盒使。但可以使用設(shè)置成其他名字,用于區(qū)分不同應(yīng)用程序的記錄七嫌。一旦設(shè)置少办,不能修改,可以通過%contextName來打印日志上下文名稱,一般來說我們不用這個(gè)屬性诵原,可有可無英妓。
<contextName>logback</contextName>
子節(jié)點(diǎn)三:<property> 設(shè)置變量
用來定義變量值的標(biāo)簽, 有兩個(gè)屬性绍赛,name和value蔓纠;其中name的值是變量的名稱,value的值時(shí)變量定義的值吗蚌。通過定義的值會(huì)被插入到logger上下文中腿倚。定義變量后,可以使“${}”來使用變量蚯妇。
<property name="logback.logdir" value="/Users/inke/dev/log/tomcat"/>
<property name="logback.appname" value="app"/>
這里可以看后通過 application.yml 傳遞參數(shù)過來
子節(jié)點(diǎn)四:<appender>
appender用來格式化日志輸出節(jié)點(diǎn)敷燎,有倆個(gè)屬性name和class,class用來指定哪種輸出策略箩言,常用就是控制臺(tái)輸出策略和文件輸出策略硬贯。
控制臺(tái)輸出ConsoleAppender:
示例一:
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<contextName>logback-demo</contextName>
<!--輸出到控制臺(tái) ConsoleAppender-->
<appender name="consoleLog1" class="ch.qos.logback.core.ConsoleAppender">
<!--展示格式 layout-->
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%d -1 %msg%n</pattern>
</layout>
</appender>
<!--輸出到控制臺(tái) ConsoleAppender-->
<appender name="consoleLog2" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d -2 %msg%n</pattern>
</encoder>
</appender>
<!--指定最基礎(chǔ)的日志輸出級別-->
<root level="INFO">
<!--appender將會(huì)添加到這個(gè)loger-->
<appender-ref ref="consoleLog1"/>
<appender-ref ref="consoleLog2"/>
</root>
</configuration>
eg:console控制臺(tái)
2018-04-16 11:37:00,116 -1 Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-04-16 11:37:00,116 -2 Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-04-16 11:37:00,853 -1 ClassTemplateLoader for Spring macros added to FreeMarker configuration
2018-04-16 11:37:00,853 -2 ClassTemplateLoader for Spring macros added to FreeMarker configuration
2018-04-16 11:37:00,904 -1
示例二:
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<contextName>logback-demo</contextName>
<!--輸出到控制臺(tái) ConsoleAppender-->
<appender name="consoleLog1" class="ch.qos.logback.core.ConsoleAppender">
<!--展示格式 layout-->
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>
<pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>
</pattern>
</layout>
<!--
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
-->
</appender>
<!--指定最基礎(chǔ)的日志輸出級別-->
<root level="INFO">
<!--appender將會(huì)添加到這個(gè)loger-->
<appender-ref ref="consoleLog1"/>
</root>
</configuration>
eg:consloe控制臺(tái)
11:44:49.005 logback-demo [restartedMain] INFO o.s.b.d.a.OptionalLiveReloadServer - LiveReload server is running on port 35729
11:44:49.102 logback-demo [restartedMain] INFO o.s.j.e.a.AnnotationMBeanExporter - Registering beans for JMX exposure on startup
11:44:49.120 logback-demo [restartedMain] INFO o.a.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-8080"]
1
<encoder>表示對日志進(jìn)行編碼:
%d{HH: mm:ss.SSS}——日志輸出時(shí)間
%thread——輸出日志的進(jìn)程名字,這在Web應(yīng)用以及異步任務(wù)處理中很有用
%-5level——日志級別陨收,并且使用5個(gè)字符靠左對齊
%logger{36}——日志輸出者的名字
%msg——日志消息
%n——平臺(tái)的換行符
參考文檔:
- Spring Boot 日志配置饭豹;
- Springboot參考指南
- Springboot實(shí)戰(zhàn),丁雪峰(譯者)