1. 概述
屬性是 Spring Boot 提供的一些最有用機制之一。它們可以從各種地方提供,例如專用屬性文件和環境變量等。因此,在調試時查找和記錄特定屬性有時會很有用。
在本簡短教程中,我們將探討幾種在 Spring Boot 應用程序中查找和記錄屬性的不同方法。
首先,我們將創建一個簡單的測試應用程序進行操作。然後,我們將嘗試三種不同的方法來記錄特定屬性。
2. 創建測試應用程序
讓我們創建一個具有三個自定義屬性的簡單應用程序。
我們可以使用 Spring Initializr 創建 Spring Boot 應用程序模板。 我們將使用 Java 作為語言。 我們可以自由選擇其他選項,例如 Java 版本、項目元數據等。
接下來,我們需要嚮應用程序添加自定義屬性。 我們將這些屬性添加到 src/main/resources 目錄下的新 application.properties 文件中:
app.name=MyApp
app.description=${app.name} is a Spring Boot application
bael.property=stagingValue3. 帶有上下文刷新事件的日誌屬性
使用 Spring Boot 應用程序中的日誌屬性的第一種方法是使用 Spring 事件,特別是 <em org.springframework.context.event.ContextRefreshedEvent</em> 類和相應的 <em EventListener</em>。 我們將演示如何記錄所有可用的屬性以及更詳細的版本,該版本僅打印來自特定文件的屬性。
3.1. 記錄所有屬性
我們先創建一個 Bean 以及事件監聽器方法:
@Component
public class AppContextRefreshedEventPropertiesPrinter {
@EventListener
public void handleContextRefreshed(ContextRefreshedEvent event) {
// event handling logic
}
}我們為事件監聽器方法添加了 org.springframework.context.event.EventListener 註解。當 ContextRefreshedEvent 發生時,Spring 會調用該方法。
下一步是獲取觸發事件實例,即 org.springframework.core.env.ConfigurableEnvironment 接口。 ConfigurableEnvironment 接口提供了一個有用的方法 getPropertySources(),我們將使用它來獲取所有屬性源列表,例如環境、JVM 或屬性文件變量:
ConfigurableEnvironment env = (ConfigurableEnvironment) event.getApplicationContext().getEnvironment();現在讓我們看看如何使用它來打印所有屬性,不僅是從application.properties 文件中獲取,還包括環境變量、JVM 變量以及其他許多內容:
env.getPropertySources()
.stream()
.filter(ps -> ps instanceof MapPropertySource)
.map(ps -> ((MapPropertySource) ps).getSource().keySet())
.flatMap(Collection::stream)
.distinct()
.sorted()
.forEach(key -> LOGGER.info("{}={}", key, env.getProperty(key)));首先,我們創建一個從可用屬性源中獲取的 Stream。然後,我們使用它的 filter() 方法來迭代那些是 org.springframework.core.env.MapPropertySource 類實例的屬性源。
正如其名稱所示,該屬性源中的屬性存儲在映射結構中。我們在下一步中使用它,即使用 map() 方法來獲取屬性鍵的集合。
接下來,我們使用 Stream 的 flatMap() 方法,因為我們希望迭代單個屬性鍵,而不是鍵的集合。我們還希望以字母順序打印出唯一的屬性,避免重複。
最後一步是記錄屬性鍵及其值。
當我們啓動應用程序時,我們應該看到從各種源中檢索的大量屬性列表:
COMMAND_MODE=unix2003
CONSOLE_LOG_CHARSET=UTF-8
...
bael.property=defaultValue
app.name=MyApp
app.description=MyApp is a Spring Boot application
...
java.class.version=52.0
ava.runtime.name=OpenJDK Runtime Environment3.2. 僅從 application.properties文件中獲取日誌屬性
如果希望僅從 application.properties文件中獲取日誌屬性,我們可以重用大部分先前代碼。 唯一需要修改的是傳遞給 filter()方法的 lambda 函數:
env.getPropertySources()
.stream()
.filter(ps -> ps instanceof MapPropertySource && ps.getName().contains("application.properties"))
...現在,啓動應用程序時,我們應該看到以下日誌:
bael.property=defaultValue
app.name=MyApp
app.description=MyApp is a Spring Boot application4. 使用 Environment 接口的日誌屬性
使用 Environment 接口設置日誌屬性的另一種方式是:
@Component
public class EnvironmentPropertiesPrinter {
@Autowired
private Environment env;
@PostConstruct
public void logApplicationProperties() {
LOGGER.info("{}={}", "bael.property", env.getProperty("bael.property"));
LOGGER.info("{}={}", "app.name", env.getProperty("app.name"));
LOGGER.info("{}={}", "app.description", env.getProperty("app.description"));
}
}與上下文刷新事件方法的唯一限制是,我們需要知道屬性名稱才能獲取其值。
環境接口不提供列出所有屬性的方法。另一方面,這絕對是一種更短、更簡單的技術。
啓動應用程序時,我們應該看到與之前相同的輸出:
bael.property=defaultValue
app.name=MyApp
app.description=MyApp is a Spring Boot application5. 使用 Spring Actuator 進行日誌配置
Spring Actuator 是一個非常實用的庫,它為我們的應用程序帶來了生產級別的特性。<em/>/env</em/> REST 端點返回當前環境屬性。
首先,讓我們將 Spring Actuator 庫添加到我們的項目中:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>3.0.0</version>
</dependency>接下來,我們需要啓用 /env 端點,因為它默認情況下已禁用。請打開 application.properties 文件並添加以下條目:
management.endpoints.web.exposure.include=env現在,我們只需要啓動應用並前往 env</em/> 端點。 在我們的情況下,地址是 http://localhost:8080/actuator/env. </em/>。 我們應該看到包含所有環境變量,包括我們自己的屬性的大量 JSON 數據:
{
"activeProfiles": [],
"propertySources": [
...
{
"name": "Config resource 'class path resource [application.properties]' via location 'optional:classpath:/' (document #0)",
"properties": {
"app.name": {
"value": "MyApp",
"origin": "class path resource [application.properties] - 10:10"
},
"app.description": {
"value": "MyApp is a Spring Boot application",
"origin": "class path resource [application.properties] - 11:17"
},
"bael.property": {
"value": "defaultValue",
"origin": "class path resource [application.properties] - 13:15"
}
}
}
...
]
}6. 結論
在本文中,我們學習瞭如何在 Spring Boot 應用程序中記錄屬性。
首先,我們創建了一個包含三個自定義屬性的測試應用程序。然後,我們看到了三種不同的方法來檢索和記錄所需屬性。