Spring使用@ConfigurationProperties
及@ConstructorBinding
將properties檔內容以建構式注入到bean。
在Spring Boot 使用@ConfigurationProperties 綁定properties至Bean中是透過setter的方式注入properties,但這樣bean的屬性無法以final
修飾因此能被修改,因此本篇改用建構式注入的方式才能加上final
並達到immutable的效果。
注意@ConstructorBinding
在Spring Boot 2.2.0版本之後才有。
範例環境:
- Java 8
- Spring Boot 2.3.2.RELEASE
- Maven
- Lombok
system.properites
為要注入bean的properties檔。
system.properties
system.name=Demo system
system.version=1.0.0
system.url=192.168.0.111
system.port=8080
注入system.properites
內容的bean,在類別名稱前加上@ConfigurationProperties
,屬性prefix
設定key的前綴。加上@ConstructorBinding
才能以建構式注入對應的properties值。
注意@ConstructorBinding
不能與由@Component
、@Bean
及@Import
的bean一起使用,Spring改以@EnableConfigurationProperties
或@ConfigurationPropertiesScan
來註冊這些constructor binding的bean。
SystemProperties
package com.abc.demo.properties;
import lombok.Getter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConstructorBinding;
@Getter
@ConstructorBinding
@ConfigurationProperties(prefix = "system")
public class SystemProperties {
private final String name; // system.name
private final String version; // system.version
private final String url; // system.url
private final String port; // system.port
public SystemProperties(
String name,
String version,
String url,
String port) {
this.name = name;
this.version = version;
this.url = url;
this.port = port;
}
}
在配置類設定@PropertySource
指定classpath下的system.properties
。加上@EnableConfigurationProperties
指定要註冊為bean的@ConstructorBinding
的類,也就是上面的SystemProperties
;或使用@ConfigurationPropertiesScan
掃描所在package下的@ConstructorBinding
的類來註冊。
DemoApplication
package com.abc.demo;
import com.abc.demo.properties.SystemProperties;
import com.abc.demo.service.DemoService;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.PropertySource;
@EnableConfigurationProperties(SystemProperties.class)
//@ConfigurationPropertiesScan
@PropertySource("classpath:system.properties")
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(DemoApplication.class, args);
DemoService demoService = ctx.getBean(DemoService.class);
demoService.printSystemPropertiesValue();
}
}
在DemoApplication.main()
中調用的DemoService
是一般的@Component(@Service)
bean。可以看到SystemProperties
雖非@Component
註冊的bean,但仍可透過@Autowired
注入。
DemoService
package com.abc.demo.service;
import com.abc.demo.properties.SystemProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class DemoService {
@Autowired
SystemProperties systemProperties;
public void printSystemPropertiesValue() {
System.out.println(systemProperties.getName());
System.out.println(systemProperties.getVersion());
System.out.println(systemProperties.getUrl());
System.out.println(systemProperties.getPort());
}
}
啟動專案印出結果。
Demo system
1.0.0
192.168.0.111
8080
參考github。
沒有留言:
張貼留言