ããã¯ããªã«ãããããŠæžãããã®ïŒ
Spring Frameworkã§ãããããã£ãã¡ã€ã«ãJavaConfigã«ãããã³ã°ããå ŽåãããšProfileãå«ããŠâŠãšããæã¯
ã©ããããã ã£ãïŒãšããã®ãããå¿ããã®ã§ã
ã¡ã¢ããŠãããããªãšã
Spring Frameworkã§ãããããã£ãã¡ã€ã«ãæ±ã
Spring Bootã§ããèšããšããŸãçã£å
ã«æããã®ã¯application.properties
ã ãšæããŸãã
èªåã§çšæããããããã£ãã¡ã€ã«ãæ±ãå Žåã¯ãã©ãããã®ã§ãããïŒ
ããšãProfileã«ã€ããŠãã
ç°å¢ã«å¿ããŠèšå®å€ãå€æŽããå Žåã¯ç°å¢å€æ°ã§ããšãã話ã«ããããšããããªãšã¯æããŸãããããã¯ããã§æŒãããŠ
ããããå
容ã§ã¯ããã®ã§ä»åæ±ãããšæããŸãã
@PropertySource
èªåã§çšæããããããã£ãã¡ã€ã«ãèªãå Žåã¯ã@PropertySource
ã¢ãããŒã·ã§ã³ã䜿ãã®ããªããšã
PropertySource (Spring Framework 5.3.6 API)
Javadocã«æžãããŠããããã«ã@PropertySource
ã¢ãããŒã·ã§ã³ïŒ@Configuration
ã¢ãããŒã·ã§ã³ã䜿ãããšã§
ããããã£ãã¡ã€ã«ã®å
容ãSpringã«çµã¿èŸŒãããšãã§ããŸãã
â»@Configuration
ã¢ãããŒã·ã§ã³ã§ã¯ãªãã@Component
ã¢ãããŒã·ã§ã³ã§ãããã®ã§ãã
@Configuration @PropertySource("classpath:/com/myco/app.properties") public class AppConfig {
ãŸããããããã£ãã¡ã€ã«å
ã«ãã«ããã€ãæåãå«ãå Žåã¯ãencoding
ãæå®ããŠèªã¿èŸŒãããã«ããã°OKã§ãã
@Configuration @PropertySource(value = "classpath:/com/myco/app.properties", encoding = "UTF-8") public class AppConfig {
SpELã䜿ããã®ã§ãProfiileããšã«ããããã£ãã¡ã€ã«ãçšæãããå Žåã¯ã以äžã®ããã«ããã°ããã§ãããã
@Configuration @PropertySource(value = "classpath:/com/myco/app-${spring.profiles.active}.properties", encoding = "UTF-8") public class AppConfig { .... }
ãŸããè€æ°ã®ããããã£ãã¡ã€ã«ãèªã¿èŸŒã¿ããå Žåã¯ã@PropertySources
ã¢ãããŒã·ã§ã³ã䜿ãããšã§
@PropertySource
ã¢ãããŒã·ã§ã³ãè€æ°æå®ããããšãã§ããŸãã
PropertySources (Spring Framework 5.3.6 API)
ãããªæãã§ãããæžããé ã«èªã¿èŸŒãŸããïŒåŸåã¡ïŒããã§ãã
@Configuration @PropertySources({ @PropertySource(value = "classpath:/com/myco/app.properties", encoding = "UTF-8"), @PropertySource(value = "classpath:/com/myco/app-${spring.profiles.active}.properties", encoding = "UTF-8") }) public class AppConfig { .... }
ãã ããã®æžãæ¹ã ãšå°ãªããšã2ã€ã®ããããã£ãã¡ã€ã«ãååšããŠããå¿
èŠããããã©ã¡ãããååšããªãå Žåã¯
äŸå€ãã¹ããŒãããŸãã
ããã§å°ãå Žåã¯ãignoreResourceNotFound
å±æ§ãtrue
ã«ããã°ãæå®ã®ãã¡ã€ã«ãååšããªãå Žåã«ç¡èŠããããšã
ã§ããŸãã
ããšãã°ãProfileæå®ã®ããããã£ãã¡ã€ã«ãååšããªãã±ãŒã¹ãããå Žåã¯ã以äžã®ãããªæå®ã«ãªããŸãã
@Configuration @PropertySources({ @PropertySource(value = "classpath:/com/myco/app.properties"), @PropertySource(value = "classpath:/com/myco/app-${spring.profiles.active}.properties", encoding = "UTF-8", ignoreResourceNotFound = true) }) public class AppConfig { .... }
@ConfigurationPropertiesã@Valueã
å€ã®ååŸã«ã¯ã@ConfigurationProperties
ã¢ãããŒã·ã§ã³ãŸãã¯@Value
ã¢ãããŒã·ã§ã³ã䜿ããŸãã
ConfigurationProperties (Spring Boot 2.4.5 API)
Value (Spring Framework 5.3.6 API)
2ã€ã®æ¹æ³ã®éãã¯ããã¡ãã«èšè¿°ããããŸãã
@ConfigurationProperties vs. @Value
@ConfigurationProperties
ã¢ãããŒã·ã§ã³ã䜿ãå ŽåãRelaxed BindingïŒããããã£åãã@ConfigurationProperties
ã
ä»äžãããBeanã®ããããã£ã«äžå®ã®ã«ãŒã«ã§ãããã³ã°ããŠãããæ©èœïŒã䜿ãããã¡ã¿ããŒã¿ã®çæãã§ããŠè£å®ã§
䟿å©ãªã©ã®ãã€ã³ãããããŸãã
äžæ¹ã§ãSpELã䜿ããã®ã¯@Value
ã ãã§ãã
ãšã¯ãããããããã£ãåå®å
šã«æ±ããã®ã¯@ConfigurationProperties
ã¢ãããŒã·ã§ã³ãªã®ã§ãåºæ¬çã«ã¯ãã¡ãã䜿ãã®ã
ããããã§ãã
Type-safe Configuration Properties
Relaxed Bindingã§ã¯prefix以éã®éšåã®ããããã£åã¯ãKebab caseãCamel caseãã¢ã³ããŒã¹ã³ã¢ïŒå€§æåãå°æåïŒã§ã®
å€æããµããŒãããŠããŸãã
ããã¥ã¡ã³ãã®äŸã§ãããšãacme.my-project.person.[ããããã£å]
ãšããããããã£ããŒã§@ConfigurationProperties
ã¢ãããŒã·ã§ã³ã§acme.my-project.person
ãprefixãšããå ŽåãBeanã®firstName
ãšããããããã£ã«ã¯ä»¥äžã®4ãã¿ãŒã³ã®
ããããã£åããã€ã³ãã§ããŸãã
acme.my-project.person.first-name
ïŒæšå¥šïŒacme.myProject.person.firstName
acme.my_project.person.first_name
ACME_MYPROJECT_PERSON_FIRSTNAME
ïŒç°å¢å€æ°ã§æå®ããå Žåã®æšå¥šïŒ
ããããã£ãã¡ã€ã«å ã§èšè¿°ããåã«ã¯ãKebab caseã§å®çŸ©ããã®ãè¯ãããã§ãã
ã¡ãªã¿ã«ã@ConfigurationProperties
ã¢ãããŒã·ã§ã³ã¯Beanãžå€ããã€ã³ãããä»çµã¿ã§ãããããå€ã®ãã€ã³ãã«ã¯
getterïŒsetterããŸãã¯ã³ã³ã¹ãã©ã¯ã¿ã§ã®ã€ã³ãžã§ã¯ã·ã§ã³ãå¿
èŠã«ãªããŸãã
ä»åã¯getterïŒsetterã䜿ãããšæããŸãã
ãããªæãã®äŸã«ãªããŸããã
@ConfigurationProperties(prefix="acme.my-project.person") public class OwnerProperties { // 以äžã®4ã€ã®ãã¿ãŒã³ããã€ã³ãå¯èœ // acme.my-project.person.first-name // acme.myProject.person.firstName // acme.my_project.person.first_name // ACME_MYPROJECT_PERSON_FIRSTNAME private String firstName; // getterïŒsetterãå¿ èŠ public String getFirstName() { return this.firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } }
@ConfigurationPropertiesScan
@ConfigurationProperties
ã¢ãããŒã·ã§ã³ãä»äžããã¯ã©ã¹ã¯ã@ConfigurationPropertiesScan
ã¢ãããŒã·ã§ã³ãåãããŠ
䜿ãããšã§BeanãšããŠæ€åºã»ç»é²ããããšãã§ããŸãã
Enabling @ConfigurationProperties-annotated types
ConfigurationPropertiesScan (Spring Boot 2.4.5 API)
Spring Boot 2.2ãã䜿ããã¢ãããŒã·ã§ã³ã ããã§ãã
@ConfigurationProperties scanning
ãã以åã¯ã@EnableConfigurationProperties
ã¢ãããŒã·ã§ã³ã§åãããšãããŠããã®ã ãšãã
ãšãã£ãŠãã@ConfigurationPropertiesScan
ã¢ãããŒã·ã§ã³ã¯@EnableConfigurationProperties
ã¢ãããŒã·ã§ã³ãä»äžããã
ã¡ã¿ã¢ãããŒã·ã§ã³ãªãã§ããã©ãã
ãããªã€ã¡ãŒãžã§äœ¿ãããšã«ãªããŸãã
@SpringBootApplication @ConfigurationPropertiesScan public class MyApplication { .... } @ConfigurationProperties(prefix = "acme.my-project") public class MyProperties { .... }
ããã§ããã®äŸã ãšMyProperties
ã¯ã©ã¹ã¯BeanãšããŠæ€åºããDIãå¯èœã«ãªããŸãã
@PropertySourceãš@ConfigurationPropertiesScan
ãããŸã§æžããšãèªåã§ããããã£ãã¡ã€ã«ãçšæããå Žåã¯ä»¥äžã®ããã«æžãã°ããã®ã§ã¯ïŒãšæãã®ã§ãããããã¯
ããŸããããŸããã
@SpringBootApplication @ConfigurationPropertiesScan public class MyApplication { .... } @PropertySource(value = "classpath:/com/myco/app.properties", encoding = "UTF-8") @ConfigurationProperties(prefix = "acme.my-project") public class MyProperties { .... }
ãã®äŸã§ãããšMyProperties
ã¯BeanãšããŠç»é²ãããã®ã§ãããèå¿ã®ããããã£å€ãã€ã³ãžã§ã¯ã·ã§ã³ãããªãç¶æ
ã«
ãªã£ãŠããŸããŸãã
ãããåé¿ããããã°@Configuration
ã¢ãããŒã·ã§ã³ãä»äžããã
@SpringBootApplication // @ConfigurationPropertiesScan // ãã®å Žåã@ConfigurationPropertiesScanã¯æå³ããªããªããªã public class MyApplication { .... } @Configuration @PropertySource(value = "classpath:/com/myco/app.properties", encoding = "UTF-8") @ConfigurationProperties(prefix = "acme.my-project") public class MyProperties { .... }
@PropertySource
ã¢ãããŒã·ã§ã³ãä»äžããã¯ã©ã¹ãšã@ConfigurationProperties
ã¢ãããŒã·ã§ã³ãä»äžããã¯ã©ã¹ã
å¥ã
ã«ãããããšããæ°ãããŸãã
@SpringBootApplication @ConfigurationPropertiesScan public class MyApplication { .... } @Configuration @PropertySource(value = "classpath:/com/myco/app.properties", encoding = "UTF-8") public class MyProperties { .... } @ConfigurationProperties(prefix = "acme.my-project") public class MyConfig { .... }
ããã¯ã@ConfigurationProperties
ã§ããããã£ãã€ã³ãžã§ã¯ã·ã§ã³ãã察象ãšããŠã@PropertySource
ãæå®ãã
èªèº«ã䜿ãã®ã¯ãã¡ã£ãŠããšãªãã§ããããã
PropertiesFactoryBean
äœè«çã«ã¯ãProperties
ã®ã€ã³ã¹ã¿ã³ã¹ãšããŠçµã¿èŸŒãå Žåã¯PropertiesFactoryBean
ã䜿ããŸãã
PropertiesFactoryBean (Spring Framework 5.3.6 API)
ãšãã¢ãããŒã·ã§ã³ãªã©ã®èª¬æã¯ãããããã«ããŠãå®éã«è©ŠããŠã¿ãŸãããã
ç°å¢
ä»åã®ç°å¢ã¯ããã¡ãã§ãã
$ java --version openjdk 11.0.11 2021-04-20 OpenJDK Runtime Environment (build 11.0.11+9-Ubuntu-0ubuntu2.20.04) OpenJDK 64-Bit Server VM (build 11.0.11+9-Ubuntu-0ubuntu2.20.04, mixed mode, sharing) $ mvn --version Apache Maven 3.8.1 (05c21c65bdfed0f71a2f2ada8b84da59348c4c5d) Maven home: $HOME/.sdkman/candidates/maven/current Java version: 11.0.11, vendor: Ubuntu, runtime: /usr/lib/jvm/java-11-openjdk-amd64 Default locale: ja_JP, platform encoding: UTF-8 OS name: "linux", version: "5.4.0-72-generic", arch: "amd64", family: "unix"
æºå
Spring Initializrã§ããããžã§ã¯ãã®äœæãè¡ããŸããä»åã¯ãäŸåé¢ä¿ã¯ç¹ã«è¿œå ããŸããã§ããã
$ curl -s https://start.spring.io/starter.tgz \ -d bootVersion=2.4.5 \ -d javaVersion=11 \ -d name=profile-spec-configuration \ -d groupId=org.littlewings \ -d artifactId=profile-spec-configuration \ -d version=0.0.1-SNAPSHOT \ -d packageName=org.littlewings.spring.configuration \ -d baseDir=profile-spec-configuration | tar zxvf - $ cd profile-spec-configuration $ find src -name '*.java' | xargs rm
å«ãŸããŠãããœãŒã¹ã³ãŒãã¯ã1床åé€ã
MavenäŸåé¢ä¿ããã³ãã©ã°ã€ã³ã®èšå®ã¯ããã¡ãã
<properties> <java.version>11</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure-processor</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
ãã¡ããããŒã¹ã«é²ããŠãããŸãããã
ãé¡
@PropertySource
ã¢ãããŒã·ã§ã³ããã³@ConfigurationProperties
ã¢ãããŒã·ã§ã³ã䜿ããããããã£ãã¡ã€ã«ãèªã¿èŸŒã¿ã€ã€
Beanã®ããããã£ã«ãããã³ã°ããŠãããŸãã
ãã®æã«ãProfileãæå®ããããªãšãŒã·ã§ã³ãè©ŠããŠã¿ãŸãããã
mainã¯ã©ã¹
ãããªãã§ãããmainã¯ã©ã¹ã¯ãã®ãããªåœ¢ã§äœæã
src/main/java/org/littlewings/spring/configuration/App.java
package org.littlewings.spring.configuration; import java.util.List; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.properties.ConfigurationPropertiesScan; import org.springframework.core.env.Environment; @SpringBootApplication public class App implements CommandLineRunner { Environment environment; MyConfiguration myConfiguration; ProfileSpecConfiguration profileSpecConfiguration; public App( Environment environment, MyConfiguration myConfiguration, ProfileSpecConfiguration profileSpecConfiguration ) { this.environment = environment; this.myConfiguration = myConfiguration; this.profileSpecConfiguration = profileSpecConfiguration; } public static void main(String... args) { SpringApplication.run(App.class, args); } @Override public void run(String... args) throws Exception { System.out.println("================================================="); System.out.printf("current Profile = %s%n", List.of(environment.getActiveProfiles())); System.out.println(); System.out.println("================================================="); System.out.println("print MyConfiguration properties"); System.out.printf(" message = %s%n", myConfiguration.getMessage()); System.out.printf(" count = %d%n", myConfiguration.getCount()); System.out.println(); System.out.println("================================================="); System.out.println("print ProfileSpecConfiguration properties"); System.out.printf(" message1 = %s%n", profileSpecConfiguration.getMessage1()); System.out.printf(" message2 = %s%n", profileSpecConfiguration.getMessage2()); System.out.printf(" count = %d%n", profileSpecConfiguration.getCount()); System.out.println(); System.out.println("================================================="); System.out.println("print application properties"); System.out.printf(" spring.application.name = %s%n", environment.getProperty("spring.application.name")); System.out.println(); System.out.println("================================================="); } }
ãã¡ãã®2ã€ã®ã¯ã©ã¹ã¯ãèªåã§äœæããããããã£ãã¡ã€ã«ã®å€ããããã³ã°ããã¯ã©ã¹ã«ãªããŸãã
MyConfiguration myConfiguration; ProfileSpecConfiguration profileSpecConfiguration;
Environment
ã¯ãçŸåšã®Profileã®ç¢ºèªãapplication.properties
ã®ç¢ºèªã«äœ¿ããŸãã
Environment environment;
Profileãå€ããããã€ã€ã以äžã®éšåã§å®éã«é©çšãããŠããããããã£å€ã確èªããŠããŸãããã
@Override public void run(String... args) throws Exception { System.out.println("================================================="); System.out.printf("current Profile = %s%n", List.of(environment.getActiveProfiles())); System.out.println(); System.out.println("================================================="); System.out.println("print MyConfiguration properties"); System.out.printf(" message = %s%n", myConfiguration.getMessage()); System.out.printf(" count = %d%n", myConfiguration.getCount()); System.out.println(); System.out.println("================================================="); System.out.println("print ProfileSpecConfiguration properties"); System.out.printf(" message1 = %s%n", profileSpecConfiguration.getMessage1()); System.out.printf(" message2 = %s%n", profileSpecConfiguration.getMessage2()); System.out.printf(" count = %d%n", profileSpecConfiguration.getCount()); System.out.println(); System.out.println("================================================="); System.out.println("print application properties"); System.out.printf(" spring.application.name = %s%n", environment.getProperty("spring.application.name")); System.out.println(); System.out.println("================================================="); }
å®è¡ã¯ã以äžã®ã³ãã³ãã§è¡ããŸãã
## Profileãæå®ããªãå Žå $ mvn spring-boot:run ## Profileãæå®ããå Žå $ mvn spring-boot:run -Dspring-boot.run.profiles=[Profileå]
ã§ã¯ãããããã£ãã¡ã€ã«ããããã³ã°ããã¯ã©ã¹ãæžããŠãããŸãã
åäžã®ããããã£ãã¡ã€ã«ãæ±ã
ãŸãã¯ãProfileãšãã£ããã®ãæèããªããåäžã®ããããã£ãã¡ã€ã«ãæ±ãã¯ã©ã¹ãæžããŠãããŸãã
ãããªæãã§äœæã
src/main/java/org/littlewings/spring/configuration/MyConfiguration.java
package org.littlewings.spring.configuration; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; @Configuration @PropertySource(value = "classpath:/my-configuration.properties", encoding = "UTF-8") @ConfigurationProperties(prefix = "my.configuration") public class MyConfiguration { String message; int count; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } }
ããããã£ãã¡ã€ã«ã¯ããããªå 容ã§çšæã
src/main/resources/my-configuration.properties
my.configuration.message=ããã«ã¡ã¯ãäžç my.configuration.count=10
@ConfigurationPropertiesScan
ã¢ãããŒã·ã§ã³ã¯äœ¿çšããŸããã
@SpringBootApplication public class App implements CommandLineRunner {
ããã§ã以äžã®å 容ã確èªããŸãã
System.out.println("================================================="); System.out.printf("current Profile = %s%n", List.of(environment.getActiveProfiles())); System.out.println(); System.out.println("================================================="); System.out.println("print MyConfiguration properties"); System.out.printf(" message = %s%n", myConfiguration.getMessage()); System.out.printf(" count = %d%n", myConfiguration.getCount()); System.out.println(); System.out.println("=================================================");
å
ã»ã©ãœãŒã¹ã³ãŒããèŒããæã«ããã®åŸãã«Profileããšã«ããããã£ãã¡ã€ã«ãçšæããã¯ã©ã¹ã®å
容ã衚瀺ããåŠçã
ãããŸããããä»åã¯ç¡èŠããŠãã ããã
å®è¡ã
$ mvn spring-boot:run
çµæã
================================================= current Profile = [] ================================================= print MyConfiguration properties message = ããã«ã¡ã¯ãäžç count = 10 =================================================
ããããã£ãã¡ã€ã«ã®å 容ãååŸã§ããŠããããšãã確èªã§ããŸãããããšãProfileã¯æå®ããŠããªãã®ã§ç©ºã§ããã
ããã§ã@Configuration
ã¢ãããŒã·ã§ã³ãåé€ããŠ
@PropertySource(value = "classpath:/my-configuration.properties", encoding = "UTF-8") @ConfigurationProperties(prefix = "my.configuration") public class MyConfiguration {
@ConfigurationPropertiesScan
ã¢ãããŒã·ã§ã³ãä»äžããŠå®è¡ãããš
@SpringBootApplication @ConfigurationPropertiesScan public class App implements CommandLineRunner {
MyConfiguration
ã¯ã©ã¹ãBeanãšããŠæ±ããŠã¯ãããã®ã®ãããããã£å€ãååŸã§ããªããªããŸãã
================================================= current Profile = [] ================================================= print MyConfiguration properties message = null count = 0 =================================================
å
è¿°ã®éãã@ConfigurationProperties
ã¢ãããŒã·ã§ã³ãä»äžããã¯ã©ã¹ã@ConfigurationPropertiesScan
ã¢ãããŒã·ã§ã³ã§
æ€åºããããã«ããŠããã€äžç·ã«@PropertySource
ã¢ãããŒã·ã§ã³ãä»äžããŠãããŸããããŸããã
ãšããããã§ã@ConfigurationProperties
ã¢ãããŒã·ã§ã³ãä»äžããã¯ã©ã¹ãš@PropertySource
ã¢ãããŒã·ã§ã³ã
ä»äžããã¯ã©ã¹ãåé¢ããŠã¿ãŸãã
@Configuration @PropertySource(value = "classpath:/my-configuration.properties", encoding = "UTF-8") class MyConfigurationProperties {} @ConfigurationProperties(prefix = "my.configuration") public class MyConfiguration {
mainã¯ã©ã¹ã¯ããã®ãŸãŸã§ãã
@SpringBootApplication @ConfigurationPropertiesScan public class App implements CommandLineRunner {
ä»åºŠã¯ããŸããããŸãã
=================================================
current Profile = []
=================================================
print MyConfiguration properties
message = ããã«ã¡ã¯ãäžç
count = 10
=================================================
ããã§ã¡ãã£ãšæ©ãã ã®ã§ãã¡ã¢çã«âŠã
Profileã«å¿ããããããã£ãã¡ã€ã«ãèªãããã«ãã
次ã¯ãProfileã«å¿ããããããã£ãã¡ã€ã«ãèªãããã«ããŠã¿ãŸãããã
mainã¯ã©ã¹ããã¯ã@ConfigurationPropertiesScan
ã¢ãããŒã·ã§ã³ã¯åé€ããŸããã
@SpringBootApplication public class App implements CommandLineRunner {
ããããã£ãã¡ã€ã«ã¯ã3ã€çšæããŸãã
Profileãªãã
src/main/resources/profile-spec-configuration.properties
profile.spec.configuration.message1=default message1 profile.spec.configuration.message2=default message2 profile.spec.configuration.count=1
developãšããProfileçžåœãProfileãªãã®ãã®ãããã²ãšã€é ç®ãæžãããŠããŸãã
src/main/resources/profile-spec-configuration-develop.properties
profile.spec.configuration.message1=develop profile message1 profile.spec.configuration.count=5
productionãšããProfileçžåœã
src/main/resources/profile-spec-configuration-production.properties
profile.spec.configuration.message1=production profile message1 profile.spec.configuration.message2=production profile only message2 profile.spec.configuration.count=10
çšæããããããã£ãã¡ã€ã«ã¯ãProfileãªãã®ãã®ãProfileæå®ããã®ãã®ãäž¡æ¹èªãããã«ããŠã¿ãŸãã
ããããã£ãã¡ã€ã«ã®å
容ããããã³ã°ããã¯ã©ã¹ã¯ããã¡ãã@PropertySource
ã¢ãããŒã·ã§ã³ã«ã€ããŠã¯ãããšã§
èšèŒããŸãã
src/main/java/org/littlewings/spring/configuration/ProfileSpecConfiguration.java
package org.littlewings.spring.configuration; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.context.annotation.PropertySources; @Configuration // ããšã§ @ConfigurationProperties(prefix = "profile.spec.configuration") public class ProfileSpecConfiguration { String message1; String message2; int count; public String getMessage1() { return message1; } public void setMessage1(String message1) { this.message1 = message1; } public String getMessage2() { return message2; } public void setMessage2(String message2) { this.message2 = message2; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } }
ããã§ãmainã¯ã©ã¹ã®ãã¡ãã®éšåã®åºåã確èªããŠãããŸãã
System.out.println("================================================="); System.out.printf("current Profile = %s%n", List.of(environment.getActiveProfiles())); System.out.println(); System.out.println("================================================="); // çç¥ System.out.println("print ProfileSpecConfiguration properties"); System.out.printf(" message1 = %s%n", profileSpecConfiguration.getMessage1()); System.out.printf(" message2 = %s%n", profileSpecConfiguration.getMessage2()); System.out.printf(" count = %d%n", profileSpecConfiguration.getCount()); System.out.println(); System.out.println("=================================================");
ãŸãã¯ããã¡ãã®å®çŸ©ã§ã@PropertySources
ã¢ãããŒã·ã§ã³ã䜿ãã@PropertySource
ã¢ãããŒã·ã§ã³ãè€æ°æå®
ã§ããããã«ããŠããŸãã
PropertySources (Spring Framework 5.3.6 API)
@Configuration @PropertySources({ @PropertySource("classpath:/profile-spec-configuration.properties"), @PropertySource("classpath:/profile-spec-configuration-${spring.profiles.active}.properties") }) @ConfigurationProperties(prefix = "profile.spec.configuration") public class ProfileSpecConfiguration {
確èªããŠã¿ãŸãã
develop Profileã
$ mvn spring-boot:run -Dspring-boot.run.profiles=develop
profile-spec-configuration-develop.properties
ãã¡ã€ã«ãšprofile-spec-configuration.properties
ãã¡ã€ã«ã®äž¡æ¹ã«
å®çŸ©ãããŠãããã®ã¯profile-spec-configuration-develop.properties
ãã¡ã€ã«ã®æ¹ãåªå
ãããããã§ãªããã®ã¯
profile-spec-configuration.properties
ã®æ¹ãæ®ã£ãŠããŸããã
================================================= current Profile = [develop] ================================================= print ProfileSpecConfiguration properties message1 = develop profile message1 message2 = default message2 count = 5 =================================================
production Profileæå®ã
$ mvn spring-boot:run -Dspring-boot.run.profiles=production
å
ã»ã©ã®çµæããäºæ³ã§ããŸããããã¡ãã¯ãã¹ãŠã®å
容ãprofile-spec-configuration-production.properties
ãã¡ã€ã«ã®å
容ã§
äžæžããããããã§ãã
================================================= current Profile = [production] ================================================= print ProfileSpecConfiguration properties message1 = production profile message1 message2 = production profile only message2 count = 10 =================================================
ã§ã¯ã@PropertySource
ã¢ãããŒã·ã§ã³ã®é çªãå
¥ãæ¿ããŠã¿ãŸãããã
@Configuration @PropertySources({ @PropertySource("classpath:/profile-spec-configuration-${spring.profiles.active}.properties"), @PropertySource("classpath:/profile-spec-configuration.properties") }) @ConfigurationProperties(prefix = "profile.spec.configuration") public class ProfileSpecConfiguration {
develop Profileã
$ mvn spring-boot:run -Dspring-boot.run.profiles=develop
ãããšãå
容ããã¹ãŠprofile-spec-configuration.properties
ãã¡ã€ã«ã®ãã®ã«ãªããŸãã
================================================= current Profile = [develop] ================================================= print ProfileSpecConfiguration properties message1 = default message1 message2 = default message2 count = 1 =================================================
production Profileæå®ã§ãåãã§ãã
$ mvn spring-boot:run -Dspring-boot.run.profiles=production
çµæã
================================================= current Profile = [production] ================================================= print ProfileSpecConfiguration properties message1 = default message1 message2 = default message2 count = 1 =================================================
ã€ãŸãã@PropertySources
ã¢ãããŒã·ã§ã³å
ã«æå®ãã@PropertySource
ã¢ãããŒã·ã§ã³ã«å®çŸ©ããããããã£ãã¡ã€ã«å
ã«
ããŒãéè€ãããã®ãããã°ãåŸåã¡ã«ãªããšããããšã§ããã
ãŸããéè€ãããªãæ¹ãããã®ããªããšã¯æããŸãâŠã
ãšããã§ããããŸã§ã®å®çŸ©ïŒã©ã¡ãã§ãæ§ããŸããïŒã§ã以äžã®ãããªããããã£ãã¡ã€ã«ãçšæããŠããªãProfileã§å®è¡ãããš
$ mvn spring-boot:run -Dspring-boot.run.profiles=staging
察å¿ããããããã£ãã¡ã€ã«ãååšããªãããšããããšã§äŸå€ãã¹ããŒãããŸãã
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [org.littlewings.spring.configuration.App]; nested exception is java.io.FileNotFoundException: class path resource [profile-spec-configuration-staging.properties] cannot be opened because it does not exist at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:189) ~[spring-context-5.3.6.jar:5.3.6] at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:331) ~[spring-context-5.3.6.jar:5.3.6] at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:247) ~[spring-context-5.3.6.jar:5.3.6] at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:311) ~[spring-context-5.3.6.jar:5.3.6] at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:112) ~[spring-context-5.3.6.jar:5.3.6] at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:746) ~[spring-context-5.3.6.jar:5.3.6] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:564) ~[spring-context-5.3.6.jar:5.3.6] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:782) ~[spring-boot-2.4.5.jar:2.4.5] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:774) ~[spring-boot-2.4.5.jar:2.4.5] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439) ~[spring-boot-2.4.5.jar:2.4.5] at org.springframework.boot.SpringApplication.run(SpringApplication.java:339) ~[spring-boot-2.4.5.jar:2.4.5] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1340) ~[spring-boot-2.4.5.jar:2.4.5] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1329) ~[spring-boot-2.4.5.jar:2.4.5] at org.littlewings.spring.configuration.App.main(App.java:31) ~[classes/:na] Caused by: java.io.FileNotFoundException: class path resource [profile-spec-configuration-staging.properties] cannot be opened because it does not exist at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:187) ~[spring-core-5.3.6.jar:5.3.6] at org.springframework.core.io.support.EncodedResource.getInputStream(EncodedResource.java:159) ~[spring-core-5.3.6.jar:5.3.6] at org.springframework.core.io.support.PropertiesLoaderUtils.fillProperties(PropertiesLoaderUtils.java:110) ~[spring-core-5.3.6.jar:5.3.6] at org.springframework.core.io.support.PropertiesLoaderUtils.fillProperties(PropertiesLoaderUtils.java:81) ~[spring-core-5.3.6.jar:5.3.6] at org.springframework.core.io.support.PropertiesLoaderUtils.loadProperties(PropertiesLoaderUtils.java:67) ~[spring-core-5.3.6.jar:5.3.6] at org.springframework.core.io.support.ResourcePropertySource.<init>(ResourcePropertySource.java:67) ~[spring-core-5.3.6.jar:5.3.6] at org.springframework.core.io.support.DefaultPropertySourceFactory.createPropertySource(DefaultPropertySourceFactory.java:37) ~[spring-core-5.3.6.jar:5.3.6] at org.springframework.context.annotation.ConfigurationClassParser.processPropertySource(ConfigurationClassParser.java:463) ~[spring-context-5.3.6.jar:5.3.6] at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:280) ~[spring-context-5.3.6.jar:5.3.6] at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:250) ~[spring-context-5.3.6.jar:5.3.6] at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:199) ~[spring-context-5.3.6.jar:5.3.6] at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:304) ~[spring-context-5.3.6.jar:5.3.6] at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:250) ~[spring-context-5.3.6.jar:5.3.6] at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:207) ~[spring-context-5.3.6.jar:5.3.6] at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:175) ~[spring-context-5.3.6.jar:5.3.6] ... 13 common frames omitted
ã€ãŸãã@PropertySource
ã¢ãããŒã·ã§ã³ã§æå®ãããã¡ã€ã«ã¯ãä»ã®å®çŸ©ã§ã¯å¿
é ã ãšããããšã§ãã
ãããå«ãªå Žåãååšããªãããšãããããã±ãŒã¹ã§ã¯ã@PropertySource
ã¢ãããŒã·ã§ã³ã®ignoreResourceNotFound
å±æ§ã
true
ã«ãããšããã§ãããã
@Configuration @PropertySources({ @PropertySource("classpath:/profile-spec-configuration.properties"), @PropertySource(value = "classpath:/profile-spec-configuration-${spring.profiles.active}.properties", ignoreResourceNotFound = true) }) @ConfigurationProperties(prefix = "profile.spec.configuration") public class ProfileSpecConfiguration {
ãã®å Žåã¯ãprofile-spec-configuration.properties
ãã¡ã€ã«ã ããå¿
é ã«ãªã£ãŠããŸãã
ãã1床å®è¡ã
$ mvn spring-boot:run -Dspring-boot.run.profiles=staging
ä»åºŠã¯å®è¡ã«æåããprofile-spec-configuration.properties
ãã¡ã€ã«ã®å
容ã衚瀺ãããŸãã
profile-spec-configuration-staging.properties
ãã¡ã€ã«ãšããååšããªããã®ã¯ãç¡èŠãããŸããããšã
================================================= current Profile = [staging] ================================================= print ProfileSpecConfiguration properties message1 = default message1 message2 = default message2 count = 1 =================================================
application.propertiesã¯ã©ããã£ãŠããã®ãïŒ
ãšããã§application.properties
ã«ã€ããŠã¯ãProfileã«å¯Ÿå¿ããŠããªãããããã£ãã¡ã€ã«ãååšããŠããªããŠããšã©ãŒã«
ãªããŸããã
ãšãããããã£ããèéå¹ããŸããããã©ããªã£ãŠãããã§ãããã
ãã¡ããèŠè¿ããŠã¿ãŸãã
ãããªããšãæžãããŠããŸãã
Config data files are considered in the following order: 1. Application properties packaged inside your jar (application.properties and YAML variants). 2. Profile-specific application properties packaged inside your jar (application-{profile}.properties and YAML variants). 3. Application properties outside of your packaged jar (application.properties and YAML variants). 4. Profile-specific application properties outside of your packaged jar (application-{profile}.properties and YAML variants).
確èªããŠã¿ãŸããããspring.application.name
ãæ±ã£ãŠã¿ãŸãã
Profileæå®ãªãã
src/main/resources/application.properties
spring.application.name=Default Application Name
develop ProfileïŒäžèº«ãªãïŒã
src/main/resources/application-develop.properties
production Profileã
src/main/resources/application-production.properties
spring.application.name=Production Application Name
mainã¯ã©ã¹ã®ããã¡ãã®éšåã§ç¢ºèªããŠã¿ãŸãããã
System.out.println("================================================="); System.out.printf("current Profile = %s%n", List.of(environment.getActiveProfiles())); System.out.println(); System.out.println("================================================="); // çç¥ System.out.println("print application properties"); System.out.printf(" spring.application.name = %s%n", environment.getProperty("spring.application.name")); System.out.println(); System.out.println("=================================================");
Profileæå®ãªãã
$ mvn spring-boot:run
çµæã
================================================= current Profile = [] ================================================= print application properties spring.application.name = Default Application Name =================================================
develop Profileã
$ mvn spring-boot:run -Dspring-boot.run.profiles=develop
çµæã
================================================= current Profile = [develop] ================================================= print application properties spring.application.name = Default Application Name =================================================
production Profileã
$ mvn spring-boot:run -Dspring-boot.run.profiles=production
çµæã
================================================= current Profile = [production] ================================================= print application properties spring.application.name = Production Application Name =================================================
ã€ãŸããåŸåã¡ã§ããã
ååšããªãProfileã
$ mvn spring-boot:run -Dspring-boot.run.profiles=staging
ãã¡ãã¯ãåé¡ãªãåããŸãã
================================================= current Profile = [staging] ================================================= print application properties spring.application.name = Default Application Name =================================================
ãœãŒã¹ã³ãŒãã¯ã©ããªã£ãŠãããïŒãšãããšãå°çšã®åŠçãçšæãããŠããã¿ããã§ããã
ãŸãšã
Spring BootïŒSpring Frameworkã§ãããããã£ãã¡ã€ã«ãJavaConfigã«ãããã³ã°ããæ¹æ³ãããšProfileã®æ±ãæ¹ã¯ïŒ
ãšããã®ãèŠè¿ããŠã¿ãŸããã
éåžžã«ããå¿ããã®ã§âŠãããŸã§ãŸãšããŠããã°ãã¡ã¢ãšããŠã¯äœ¿ããããªããšã
ããšãã¡ãããšæåã®ç¢ºèªãã§ããã®ã§ããã£ãŠãããŠè¯ãã£ãããªãšæããŸãã