SpringBoot外部化配置示例解析
SpringBoot外部化配置(基于2.4.0以后)
Spring Boot可以讓你將配置外部化,這樣你就可以在不同的環(huán)境中使用相同的應(yīng)用程序代碼。 你可以使用各種外部配置源,包括Java properties 文件、YAML文件、環(huán)境變量和命令行參數(shù)。
屬性值可以通過(guò)使用 @Value 注解直接注入你的Bean,也可以通過(guò)Spring 的 Environment 訪問(wèn),或者通過(guò) @ConfigurationProperties 綁定到對(duì)象。同時(shí) Spring Boot 也提供了一種非常特殊的 PropertyOrder,來(lái)允許用戶可以在適當(dāng)?shù)膱?chǎng)景下覆蓋某些屬性值,該順序旨在允許合理地覆蓋值。
按以下順序優(yōu)先級(jí)從低到高, 后者的屬性值覆蓋前者 ,所有的配置會(huì)形成互補(bǔ)配置:
默認(rèn)屬性(使用 SpringApplication.setDefaultProperties 指定)
@Configuration類上的@PropertySource注解引入的配置屬性
請(qǐng)注意,這樣的屬性源直到ApplicationContext被刷新時(shí)才會(huì)被添加到環(huán)境中。這對(duì)于配置某些屬性來(lái)說(shuō)已經(jīng)太晚了,比如logging.* 和spring.main.* ,它們?cè)谒⑿麻_(kāi)始前就已經(jīng)被讀取了。
配置數(shù)據(jù)(例如application.properties文件)
對(duì)于random.*形式的屬性,優(yōu)先從RandomValuePropertySource獲取(指優(yōu)先于后者)
OS environment variables((操作系統(tǒng)環(huán)境變量)
Java System properties(Java 系統(tǒng)屬性System.getProperties())
JNDI 屬性
ServletContext 的 初始化參數(shù)
ServletConfig 的 初始化參數(shù)
SPRING_APPLICATION_JSON 屬性
命令行參數(shù)
test 模塊下的 properties 屬性
test 模塊下 @TestPropertySource 注解引入的配置文件
啟用 devtools 時(shí) $HOME/.config/spring-boot 路徑下的配置
配置數(shù)據(jù)文件按以下加載順序考慮:
- 打包在 jar 中的應(yīng)用程序?qū)傩裕╝pplication.properties 和 YAML)
- 打包在 jar 中的特定配置文件的應(yīng)用程序?qū)傩裕╝pplication-{profile}.properties 和 YAML)
- 打包 jar 之外的應(yīng)用程序?qū)傩裕╝pplication.properties 和 YAML)
- 打包 jar 之外的特定配置文件的應(yīng)用程序?qū)傩裕╝pplication-{profile}.properties 和 YAML)
SpringBoot配置文件
Spring中常見(jiàn)的配置文件類型
- XML資源
- Properties資源
- YAML資源
Profile概述
Profile 本質(zhì)上代表一種用于組織配置信息的維度,在不同場(chǎng)景下可以代表不同的含義。例如,如果 Profile 代表的是一種狀態(tài),我們可以使用 open、halfopen、close 等值來(lái)分別代表全開(kāi)、半開(kāi)和關(guān)閉等。再比如系統(tǒng)需要設(shè)置一系列的模板,每個(gè)模板中保存著一系列配置項(xiàng)。
配置命名規(guī)則:
/{application}.yml
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
配置文件加載順序
Spring Boot 啟動(dòng)時(shí),會(huì)自動(dòng)加載 JAR 包內(nèi)部及 JAR 包所在目錄指定位置的配置文件(Properties 文件、YAML 文件)。列表按優(yōu)先級(jí)排序(較低項(xiàng)目的值覆蓋較早項(xiàng)目的值)
classpath( –classpath )
classpath 根路徑
classpath 下的 /config 包
當(dāng)前目錄( –file )
當(dāng)前目錄下
當(dāng)前目錄下的 config/ 子目錄
當(dāng)前目錄下的 config/ 子目錄的直接子目錄
. project-sample ├── config │ ├── application.yml (4) │ └── src/main/resources | │ ├── application.yml (1) | │ └── config | | │ ├── application.yml (2) ├── application.yml (3)
啟動(dòng)時(shí)加載配置文件順序:1 > 2 > 3 > 4
Profile 配置覆蓋變更(2.4.0以后)
2.4.0以前版本,默認(rèn)情況的加載順序如下:
- 打包在 jar 中的應(yīng)用程序?qū)傩裕╝pplication.properties 和 YAML)。
- 打包 jar 之外的應(yīng)用程序?qū)傩裕╝pplication.properties 和 YAML)
- 打包在 jar 中的特定于配置文件的應(yīng)用程序?qū)傩裕╝pplication-{profile}.properties 和 YAML)
- 打包 jar 之外的特定于配置文件的應(yīng)用程序?qū)傩裕╝pplication-{profile}.properties 和 YAML)
注意:在之前的版本中,JAR 包外部的application.properties配置文件不會(huì)覆蓋 JAR 包里面的基于 "profile" 的application-{profile}.properties 配置文件。
2.4.0以后版本,默認(rèn)情況的搜索順序如下:保證了 JAR 包外部的應(yīng)用程序參數(shù)應(yīng)優(yōu)先于 JAR 包內(nèi)部的特定激活的配置參數(shù)
- 打包在 jar 中的應(yīng)用程序?qū)傩裕╝pplication.properties 和 YAML)。
- 打包在 jar 中的特定于配置文件的應(yīng)用程序?qū)傩裕╝pplication-{profile}.properties 和 YAML)
- 打包 jar 之外的應(yīng)用程序?qū)傩裕╝pplication.properties 和 YAML)
- 打包 jar 之外的特定于配置文件的應(yīng)用程序?qū)傩裕╝pplication-{profile}.properties 和 YAML)
注意:同一位置下,Properties 文件優(yōu)先級(jí)高于 YAML 文件 , 如果Spring Boot在優(yōu)先級(jí)更高的位置找到了配置,那么它就會(huì)無(wú)視優(yōu)先級(jí)低的配置。
文檔排序(2.4.0以后)
從 Spring Boot 2.4 開(kāi)始,加載 Properties 和 YAML 文件時(shí)候會(huì)遵循, 在文檔中聲明排序靠前的屬性將被靠后的屬性覆蓋 。
激活指定配置文件
命令行激活: --spring.profiles.active=prod
spring:
profiles:
active: dev #激活開(kāi)發(fā)環(huán)境配置
配置文件激活如上,只需要在application.yml或者properties文件中配置即可
注意:在application.yml或者properties文件存在的情況下,不管激活的是prod還是dev,還是會(huì)讀取默認(rèn)的配置文件,只不過(guò)指定的配置文件會(huì)覆蓋默認(rèn)配置文件中的屬性
導(dǎo)入額外的配置文件(2.4.0以后)
可以使用spring.config.import屬性從其他地方導(dǎo)入更多的配置數(shù)據(jù),比如spring.config.import=my.yaml 。它會(huì)將 my.yaml 文件作為臨時(shí)文件放在當(dāng)前配置文件之后處理,因此其屬性具有更高的優(yōu)先級(jí)
激活外部配置文件
在運(yùn)行Jar包的命令中加入這個(gè)參數(shù)就可以指定Jar包以外的配置文件的位置了,也可以在application的配置文件中配置該屬性
$ java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties
這個(gè)參數(shù)就是指定外部application.yml配置文件位置的參數(shù),它支持classpath和file路徑
java -jar myproject.jar --spring.config.name=myproject
如果您不喜歡application.properties作為配置文件名,您可以通過(guò)指定spring.config.name環(huán)境屬性來(lái)切換到另一個(gè)文件名
optional可選的配置文件
對(duì)于spring.config.location、spring.config.additional-location和spring.config.import等屬性的路徑,添加optional:前綴,則當(dāng)對(duì)應(yīng)文件不存在時(shí)應(yīng)用仍可以正常啟動(dòng)
比如spring.config.location=optional:file:/my.yaml,當(dāng)應(yīng)用啟動(dòng)加載文件 my.yaml 不存在時(shí),不會(huì)拋出異常
嵌入系統(tǒng)配置信息
例如,如果想要獲取當(dāng)前應(yīng)用程序的名稱并作為一個(gè)配置項(xiàng)進(jìn)行管理,那么很簡(jiǎn)單,我們直接通過(guò) ${spring.application.name} 占位符:
myapplication.name : ${spring.application.name}
假設(shè)我們使用 Maven 來(lái)構(gòu)建應(yīng)用程序,那么可以按如下所示的配置項(xiàng)來(lái)動(dòng)態(tài)獲取與系統(tǒng)構(gòu)建過(guò)程相關(guān)的信息:
info:
app:
encoding: @project.build.sourceEncoding@
java:
source: @java.version@
target: @java.version@
# 等同于下述效果
info:
app:
encoding: UTF-8
java:
source: 1.8.0_31
target: 1.8.0_31
配置參數(shù)提示
additional-spring-configuration-metadata.json、spring-configuration-metadata.json在springboot-starter官方項(xiàng)目或第三方starter項(xiàng)目中隨處可見(jiàn),那它起的作用是什么?
- 配置
additional-spring-configuration-metadata.json文件后,在開(kāi)發(fā)人員的IDE工具使用個(gè)人編寫(xiě)的配置讀取很有效的在application.properties或application.yml文件下完成提示
配置處理器
在Maven中,該依賴關(guān)系應(yīng)被聲明為可選的,如以下例子所示。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
創(chuàng)建additional-spring-configuration-metadata.json
在resources/META-INF目錄下創(chuàng)建additional-spring-configuration-metadata.json,分類為 “groups” 或 “properties”,附加值提示分類為 "hints",如以下例子所示:
{
"groups": [
{
"name": "server",
"type": "org.springframework.boot.autoconfigure.web.ServerProperties",
"sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties"
},
{
"name": "spring.jpa.hibernate",
"type": "org.springframework.boot.autoconfigure.orm.jpa.JpaProperties$Hibernate",
"sourceType": "org.springframework.boot.autoconfigure.orm.jpa.JpaProperties",
"sourceMethod": "getHibernate()"
}
...
],
"properties": [
{
"name": "server.port",
"type": "java.lang.Integer",
"sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties"
},
{
"name": "server.address",
"type": "java.net.InetAddress",
"sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties"
},
{
"name": "spring.jpa.hibernate.ddl-auto",
"type": "java.lang.String",
"description": "DDL mode. This is actually a shortcut for the "hibernate.hbm2ddl.auto" property.",
"sourceType": "org.springframework.boot.autoconfigure.orm.jpa.JpaProperties$Hibernate"
}
...
],
"hints": [
{
"name": "spring.jpa.hibernate.ddl-auto",
"values": [
{
"value": "none",
"description": "Disable DDL handling."
},
{
"value": "validate",
"description": "Validate the schema, make no changes to the database."
},
{
"value": "update",
"description": "Update the schema if necessary."
},
{
"value": "create",
"description": "Create the schema and destroy previous data."
},
{
"value": "create-drop",
"description": "Create and then destroy the schema at the end of the session."
}
]
}
]
}
Property 屬性
properties 數(shù)組中包含的JSON對(duì)象可以包含下表中描述的屬性。
| Name | 類型 | 目的 |
|---|---|---|
| name | String | 屬性的全名。 名稱采用小寫(xiě)的句號(hào)分隔形式(例如,server.address)。 這個(gè)屬性是強(qiáng)制性的。 |
| type | String | 該屬性的數(shù)據(jù)類型的完整簽名(例如,java.lang.String),但也有完整的通用類型(例如 java.util.Map<java.lang.String,com.example.MyEnum>)。 您可以使用此屬性來(lái)指導(dǎo)用戶可以輸入的值的類型。 為了保持一致性,基元的類型是通過(guò)使用其包裝類型來(lái)指定的(例如,boolean 變成 java.lang.Boolean)。 如果該類型不知道,可以省略。 |
| description | String | 可以顯示給用戶的該property的簡(jiǎn)短描述。 如果沒(méi)有描述,可以省略。 描述中的最后一行應(yīng)以句號(hào)(.)結(jié)束。 |
| sourceType | String | 貢獻(xiàn)此屬性的來(lái)源的類名。 例如,如果該屬性來(lái)自于一個(gè)用 @ConfigurationProperties 注解的類,該屬性將包含該類的完全限定名稱。 如果源類型未知,可以省略。 |
| defaultValue | Object | 默認(rèn)值,如果沒(méi)有指定該屬性,則使用該值。 如果該屬性的類型是一個(gè)數(shù)組,它可以是一個(gè)數(shù)組的值。 如果默認(rèn)值是未知的,它可以被省略。 |
| deprecation | Deprecation | 指定該屬性是否被廢棄。 如果該字段沒(méi)有被廢棄,或者不知道該信息,可以省略。 下表提供了關(guān)于 deprecation 屬性的更多細(xì)節(jié)。 |
Hint 屬性
包含在 hints 數(shù)組中的JSON對(duì)象可以包含下表中的屬性。
| Name | 類型 | 目的 |
|---|---|---|
| name | String | 此提示所指向的屬性的全名。 名稱采用小寫(xiě)的句號(hào)分隔形式(如 spring.mvc.servlet.path)。 這個(gè)屬性是強(qiáng)制性的。 |
| values | ValueHint[] | 由 ValueHint 對(duì)象定義的有效值的列表(在下表中描述)。 每個(gè)條目都定義了值,并且可以有一個(gè)description。 |
每個(gè) hint 元素的 values 屬性中包含的JSON對(duì)象可以包含下表中描述的屬性。
| Name | 類型 | 目的 |
|---|---|---|
| value | Object | 提示所指的元素的一個(gè)有效值。 如果該屬性的類型是一個(gè)數(shù)組,它也可以是一個(gè)數(shù)組的值。 這個(gè)屬性是強(qiáng)制性的。 |
| description | String | 可以顯示給用戶的價(jià)值的簡(jiǎn)短描述。 如果沒(méi)有描述,可以省略。 描述中的最后一行應(yīng)以句號(hào)(.)結(jié)束。 |
SpringBoot命令行參數(shù)
參考:http://chabaoo.cn/article/191629.htm
啟動(dòng)Spring Boot項(xiàng)目時(shí)傳遞參數(shù),有三種參數(shù)形式:
- 選項(xiàng)參數(shù),基本格式為
--optName[=optValue](--為連續(xù)兩個(gè)減號(hào))
--foo --foo=bar --foo="bar then baz" --foo=bar,baz,biz
- 非選項(xiàng)參數(shù)
java -jar xxx.jar abc def
- 系統(tǒng)參數(shù)
java -jar -Dserver.port=8081 xxx.jar
相當(dāng)于 SpringBoot 基于 Java 命令行參數(shù)中的非選項(xiàng)參數(shù)自定義了選項(xiàng)參數(shù)的規(guī)則,具體可以看解析器SimpleCommandLineArgsParser,它里面調(diào)用其parse方法對(duì)參數(shù)進(jìn)行解析
class SimpleCommandLineArgsParser {
public CommandLineArgs parse(String... args) {
CommandLineArgs commandLineArgs = new CommandLineArgs();
for (String arg : args) {
// --開(kāi)頭的選參數(shù)解析
if (arg.startsWith("--")) {
// 獲得key=value或key值
String optionText = arg.substring(2, arg.length());
String optionName;
String optionValue = null;
// 如果是key=value格式則進(jìn)行解析
if (optionText.contains("=")) {
optionName = optionText.substring(0, optionText.indexOf('='));
optionValue = optionText.substring(optionText.indexOf('=')+1, optionText.length());
} else {
// 如果是僅有key(--foo)則獲取其值
optionName = optionText;
}
// 如果optionName為空或者optionValue不為空但optionName為空則拋出異常
if (optionName.isEmpty() || (optionValue != null && optionValue.isEmpty())) {
throw new IllegalArgumentException("Invalid argument syntax: " + arg);
}
// 封裝入CommandLineArgs
commandLineArgs.addOptionArg(optionName, optionValue);
} else {
commandLineArgs.addNonOptionArg(arg);
}
}
return commandLineArgs;
}
}
參數(shù)值的獲取
如果您需要訪問(wèn)傳遞給應(yīng)用程序的參數(shù)SpringApplication.run(…),您可以注入一個(gè)ApplicationArguments。該ApplicationArguments接口提供對(duì)原始String[]參數(shù)以及選項(xiàng)參數(shù)和非選項(xiàng)參數(shù)的訪問(wèn),如以下示例所示:
@Component
public class MyBean {
@Autowired
public MyBean(ApplicationArguments args) {
boolean debug = args.containsOption("debug");
List<String> files = args.getNonOptionArgs();
// if run with "--debug logfile.txt" debug=true, files=["logfile.txt"]
}
}
- 另外,選項(xiàng)參數(shù),也可以直接通過(guò)
@Value在類中獲取 - 系統(tǒng)參數(shù)可以通過(guò)java.lang.System提供的方法獲取
參數(shù)值的區(qū)別
關(guān)于參數(shù)值區(qū)別,重點(diǎn)看選項(xiàng)參數(shù)和系統(tǒng)參數(shù)。通過(guò)上面的示例我們已經(jīng)發(fā)現(xiàn)使用選項(xiàng)參數(shù)時(shí),參數(shù)在命令中是位于xxx.jar之后傳遞的,而系統(tǒng)參數(shù)是緊隨java -jar之后。
如果不按照該順序進(jìn)行執(zhí)行,比如使用如下方式使用選項(xiàng)參數(shù):
java -jar --server.port=8081 xxx.jar
則會(huì)拋出如下異常:
Unrecognized option: --server.port=8081 Error: Could not create the Java Virtual Machine. Error: A fatal exception has occurred. Program will exit.
如果將系統(tǒng)參數(shù)放在jar包后面,問(wèn)題會(huì)更嚴(yán)重,會(huì)出現(xiàn)可以正常啟動(dòng),但參數(shù)無(wú)法生效。這個(gè)錯(cuò)誤是最坑的,所以一定謹(jǐn)記:通過(guò)-D傳遞系統(tǒng)參數(shù)時(shí),務(wù)必放置在待執(zhí)行的jar包之前。
擴(kuò)展“外部化配置”屬性源


SpingBoot怎么支持YAML配置文件解析?
處理@PropertySource注解從ConfigurationClassParser#processPropertySource方法進(jìn)
Spring中@PropertySource默認(rèn)不支持YAML格式的解析,但是SpringBoot的配置文件卻可以解析YAML,這說(shuō)明SpringBoot中已經(jīng)實(shí)現(xiàn)了YAML文件的解析,我們只需要復(fù)用即可,我們可以看該注解源碼
/**
* Specify a custom {@link PropertySourceFactory}, if any.
* <p>By default, a default factory for standard resource files will be used.
* @since 4.3
* @see org.springframework.core.io.support.DefaultPropertySourceFactory
* @see org.springframework.core.io.support.ResourcePropertySource
*/
Class<? extends PropertySourceFactory> factory() default PropertySourceFactory.class;
PropertySourceFactory的默認(rèn)實(shí)現(xiàn)是DefaultPropertySourceFactory
public class DefaultPropertySourceFactory implements PropertySourceFactory {
@Override
public PropertySource<?> createPropertySource(@Nullable String name, EncodedResource resource) throws IOException {
return (name != null ? new ResourcePropertySource(name, resource) : new ResourcePropertySource(resource));
}
}
ResourcePropertySource默認(rèn)不支持YAML,所以我們可以通過(guò)實(shí)現(xiàn)PropertySourceFactory接口,然后用@PropertySource的factory屬性來(lái)實(shí)現(xiàn)YAML的解析
public class YamlPropertySourceFactory implements PropertySourceFactory {
@Override
public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
YamlPropertiesFactoryBean yamlPropertiesFactoryBean = new YamlPropertiesFactoryBean();
yamlPropertiesFactoryBean.setResources(resource.getResource());
Properties yamlProperties = yamlPropertiesFactoryBean.getObject();
return new PropertiesPropertySource(name, yamlProperties);
}
}
關(guān)于ApplicationEnvironmentPreparedEvent沒(méi)有被執(zhí)行的原因
官方文檔中有說(shuō)到:有些事件實(shí)際上是在ApplicationContext被創(chuàng)建之前觸發(fā)的,所以我們不能將這些事件的監(jiān)聽(tīng)器注冊(cè)為@Bean。
因?yàn)檫@個(gè)時(shí)候應(yīng)用上下文還沒(méi)有被創(chuàng)建,也就是說(shuō)監(jiān)聽(tīng)器也還沒(méi)有被初始化,這個(gè)先后順序不對(duì),會(huì)導(dǎo)致這些事件的監(jiān)聽(tīng)器不會(huì)被觸發(fā)
但可以使用SpringApplication.addListeners(...) 方法或SpringApplicationBuilder.listeners(...) 方法注冊(cè)它們。
如果您希望這些偵聽(tīng)器自動(dòng)注冊(cè)的話,可以通過(guò)新建一個(gè)META-INF/spring.factories文件,添加類似以下內(nèi)容,SpringBoot會(huì)自動(dòng)幫你注冊(cè)。
org.springframework.context.ApplicationListener=com.example.project.MyListener
應(yīng)用程序事件
應(yīng)用程序運(yùn)行時(shí),應(yīng)用程序事件按以下順序發(fā)送:官方鏈接
- An ApplicationStartingEvent is sent at the start of a run but before any processing, except for the registration of listeners and initializers.
- An ApplicationEnvironmentPreparedEvent is sent when the Environment to be used in the context is known but before the context is created.
- An ApplicationContextInitializedEvent is sent when the ApplicationContext is prepared and ApplicationContextInitializers have been called but before any bean definitions are loaded.
- An ApplicationPreparedEvent is sent just before the refresh is started but after bean definitions have been loaded.
- An ApplicationStartedEvent is sent after the context has been refreshed but before any application and command-line runners have been called.
- An AvailabilityChangeEvent is sent right after with LivenessState.CORRECT to indicate that the application is considered as live.
- An ApplicationReadyEvent is sent after any application and command-line runners have been called.
- An AvailabilityChangeEvent is sent right after with ReadinessState.ACCEPTING_TRAFFIC to indicate that the application is ready to service requests.
- An ApplicationFailedEvent is sent if there is an exception on startup.
The above list only includes SpringApplicationEvents that are tied to a SpringApplication. In addition to these, the following events are also published after ApplicationPreparedEvent and before ApplicationStartedEvent:
- A WebServerInitializedEvent is sent after the WebServer is ready. ServletWebServerInitializedEvent and ReactiveWebServerInitializedEvent are the servlet and reactive variants respectively.
- A ContextRefreshedEvent is sent when an ApplicationContext is refreshed.
以上就是SpringBoot外部化配置示例解析的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot外部化配置的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringBoot Application的exclude不生效問(wèn)題及排查
這篇文章主要介紹了SpringBoot Application的exclude不生效問(wèn)題及排查,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11
SpringBoot項(xiàng)目application.yml文件數(shù)據(jù)庫(kù)配置密碼加密的方法
這篇文章主要介紹了SpringBoot項(xiàng)目application.yml文件數(shù)據(jù)庫(kù)配置密碼加密的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03
使用Spring AOP監(jiān)控指定方法執(zhí)行時(shí)間的代碼詳解
這篇文章主要介紹了使用Spring AOP監(jiān)控指定方法執(zhí)行時(shí)間,文中通過(guò)代碼示例給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-08-08
java.math.BigDecimal的用法及加減乘除計(jì)算
這篇文章主要介紹了java.math.BigDecimal的用法及加減乘除計(jì)算,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05
Springboot+Flowable?快速實(shí)現(xiàn)工作流的開(kāi)發(fā)流程
這篇文章主要介紹了Springboot+Flowable?快速實(shí)現(xiàn)工作流的開(kāi)發(fā)流程,本文通過(guò)實(shí)例代碼圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-02-02
Spring高級(jí)注解@PropertySource詳細(xì)解讀
這篇文章主要介紹了Spring高級(jí)注解@PropertySource詳細(xì)解讀,@PropertySource注解用于指定資源文件讀取的位置,它不僅能讀取properties文件,也能讀取xml文件,并且通過(guò)YAML解析器,配合自定義PropertySourceFactory實(shí)現(xiàn)解析yaml文件,需要的朋友可以參考下2023-11-11

