๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Springboot

[spring boot] ์™ธ๋ถ€ ์„ค์ •

 

https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-external-config

์™ธ๋ถ€ ์„ค์ •์ด๋ž€?

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์—ฌ๋Ÿฌ ์„ค์ • ๊ฐ’๋“ค์„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์•ˆ ๋˜๋Š” ๋ฐ–์—๋‹ค๊ฐ€ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ

application.properties

๊ฐ€์žฅ ์ค‘์š”ํ•œ ์„ค์ • ํŒŒ์ผ์€ application.properties ํŒŒ์ผ์ด๋‹ค.

spring boot๊ฐ€ ์ž๋™์œผ๋กœ ๋กœ๋”ฉํ•˜๋Š” ํŒŒ์ผ ์ด๋ฆ„์œผ๋กœ, ๊ทœ์•ฝ(convention)์ด๋‹ค.

key value ํ˜•ํƒœ๋กœ ์ •์˜ํ•œ๋‹ค. ๋‹ค ๋ฌธ์ž์—ด์ด๋‹ค.

springboot intializr ์‹œ ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋˜๋Š” ํŒŒ์ผ๋กœ, ๋ฐ‘์˜ ์šฐ์„ ์ˆœ์œ„์—์„œ 15์ˆœ์œ„์— ํ•ด๋‹นํ•œ๋‹ค.

Spring Boot์˜ ์™ธ๋ถ€ ์„ค์ • ์ข…๋ฅ˜

  • properties

  • YAML

  • ํ™˜๊ฒฝ ๋ณ€์ˆ˜

  • ์ปค๋งจ๋“œ ๋ผ์ธ ์•„๊ทœ๋จผํŠธ

โšก ํ”„๋กœํผํ‹ฐ ์šฐ์„  ์ˆœ์œ„

  1. ์œ ์ € ํ™ˆ ๋””๋ ‰ํ† ๋ฆฌ์— ์žˆ๋Š” spring-boot-dev-tools.properties

  2. @TestPropertySource(locations="classpath:/test.properties") ใ…ก> ๋‚ด๊ฐ€ ์“ฐ๊ณ  ์ •๋ฆฌํ•œ ์ฝ”๋“œ # , + ์•„๋ž˜์™€ ๊ฐ™์ด properties ์†์„ฑ๋„ ์“ธ ์ˆ˜ ์žˆ๋‹ค.

  3. @SpringBootTest(properties="jueun.name=jueun3") ใ…ก> ๋‚ด๊ฐ€ ์“ฐ๊ณ  ์ •๋ฆฌํ•œ ์ฝ”๋“œ #

  4. ์ปค๋งจ๋“œ ๋ผ์ธ ์•„๊ทœ๋จผํŠธ ใ…ก> java -jar target/demo-0.0.1-SNAPSHOT.jar --jueun.name=hoit1302

  5. SPRING_APPLICATION_JSON (ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ๋˜๋Š” ์‹œ์Šคํ…œ ํ”„๋กœํ‹ฐ) ์— ๋“ค์–ด์žˆ๋Š” ํ”„๋กœํผํ‹ฐ

  6. ServletConfig ํŒŒ๋ผ๋ฏธํ„ฐ

  7. ServletContext ํŒŒ๋ผ๋ฏธํ„ฐ

  8. java:comp/env JNDI ์• ํŠธ๋ฆฌ๋ทฐํŠธ

  9. System.getProperties() ์ž๋ฐ” ์‹œ์Šคํ…œ ํ”„๋กœํผํ‹ฐ

  10. OS ํ™˜๊ฒฝ ๋ณ€์ˆ˜

  11. RandomValuePropertySource

  12. JAR ๋ฐ–์— ์žˆ๋Š” ํŠน์ • ํ”„๋กœํŒŒ์ผ์šฉ application properties

  13. JAR ์•ˆ์— ์žˆ๋Š” ํŠน์ • ํ”„๋กœํŒŒ์ผ์šฉ application properties ใ…ก> application-{profile}.properties #

  14. JAR ๋ฐ–์— ์žˆ๋Š” application properties

  15. JAR ์•ˆ์— ์žˆ๋Š” application properties ใ…ก> springboot intializr ์‹œ ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋˜๋Š” ํŒŒ์ผ

  16. @PropertySource

  17. ๊ธฐ๋ณธ ํ”„๋กœํผํ‹ฐ (SpringApplication.setDefaultProperties) ใ…ก> ์•„๋ฌด๊ฒƒ๋„ ์•ˆ ์ผ์„ ๋•Œ

 

test/resources/application.properties ์žˆ์„ ๋•Œ

testApplication์„ ์‹คํ–‰ ์‹œ

๋นŒ๋“œ๋ฅผ ํ•  ๋•Œ src ๋ฐ‘์— ์žˆ๋Š” ๊ฒƒ(src/main/java, src/main/resources)์„ ๋นŒ๋“œ๋ฅผ ํ•ด์„œ classpath์— ๋†“๊ณ  ๊ทธ ๋‹ค์Œ์— test ์ฝ”๋“œ๋ฅผ ๋นŒ๋“œํ•ด์„œ classpath์— ๋†“๋Š”๋‹ค. ๊ทธ ๋•Œ application.properties๊ฐ€ test ํด๋” ๋ฐ‘์— ์žˆ๋Š” ๊ฒƒ์œผ๋กœ ์˜ค๋ฒ„๋ผ์ด๋”ฉ๋œ๋‹ค.

์ด ์ฝ”๋”ฉ ๋ฐฉ์‹์€ ํฐ ๋‹จ์ ์ด ์žˆ๋‹ค. #

test/resources/test.properties ์žˆ์„ ๋•Œ #

์šฐ์„  ์ˆœ์œ„ 2์ˆœ์œ„์ธ @TestPropertySource(locations="classpath:/test.properties") ์™€ ์—ฐ๊ฒฐ๋˜๋Š” ์ด์•ผ๊ธฐ์ด๋‹ค.

test/resources์— application.properties๋ฅผ ์ง€์šฐ๊ณ  test.properties์„ ์ผ๋‹ค.
๋นŒ๋“œ๋ฅผ ํ•  ๋•Œ src ๋ฐ‘์— ์žˆ๋Š” ๊ฒƒ(src/main/java, src/main/resources)์„ ๋นŒ๋“œ๋ฅผ ํ•ด์„œ classpath์— ๋†“๊ณ 
๊ทธ ๋‹ค์Œ์— test ์ฝ”๋“œ๋ฅผ ๋นŒ๋“œํ•ด์„œ classpath์— ๋†“๋Š”๋‹ค.
๊ทธ ๋•Œ application.properties์™€ test ํด๋” ๋ฐ‘์— ์žˆ๋Š” test.properties๋Š” ํŒŒ์ผ ๋ช…์ด ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ๋‘˜ ๋‹ค ์˜จ์ „ํžˆ ์žˆ๋‹ค.
๊ทธ๋Ÿฐ๋ฐ ์‹คํ–‰ํ•œ ์ด ํ…Œ์ŠคํŠธ์—์„œ @TestPropertySource(locations = "classpath:/test.properties")๋กœ
์ถ”๊ฐ€๋กœ test.properties์„ ์‚ฌ์šฉํ•˜๋ผ๊ณ  ํ•œ๋‹ค.
2์ˆœ์œ„๋กœ ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’๊ธฐ์— ๋™์ผํ•œ ํ‚ค๊ฐ’์ด ์žˆ์„ ๋•Œ๋งŒ, ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•œ๋‹ค.
๊ทธ๋ž˜์„œ main ๋ฐ‘ application.properties ์— ์žˆ๋Š” JUEUN์ด ์•„๋‹Œ, test.properties์— ์žˆ๋Š” jueun22๊ฐ€ ํ™•์ธ๋œ๋‹ค.

โšก application.properties ์šฐ์„  ์ˆœ์œ„

  1. file:./config/

  2. file:./

  3. classpath:/config/

  4. classpath:/

ํ”„๋กœํผํ‹ฐ์˜ ๊ฐ’์„ ์ฐธ์กฐํ•˜๋Š” @Value

@Component
public class SampleRunner implements ApplicationRunner {

    @Value("${jueun.name}")
    private String name;


    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("=====================");
        System.out.println(name);
        System.out.println("=====================");
    }
}

 

SpringEL ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์— ์žˆ๋Š” ๋ฐ‘์—์„œ ์„ค๋ช…ํ•˜๋Š” Property Type Conversion, @Validated ๊ธฐ๋Šฅ๋“ค์€ ์ „๋ถ€ ์‚ฌ์šฉ ๋ชปํ•œ๋‹ค.

* ๋ณด์ถฉ

๋žœ๋ค๊ฐ’ ์„ค์ •ํ•˜๊ธฐ

  • ${random.int}, ${random.double}

  • ${random.int(0,100)} ใ…ก> ๊ณต๋ฐฑ์ด ์žˆ์œผ๋ฉด ์—๋Ÿฌ๋‚œ๋‹ค.

  • ์ฃผ์˜, ํฌํŠธ๋ฒˆํ˜ธ๋Š” 0์œผ๋กœ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์ด ๋žœ๋ค๊ฐ’!

 

ํ”Œ๋ ˆ์ด์Šค ํ™€๋”

  • jueun.id=hoit1302

  • jueun.email=${jueun.id}@ewhain.net

Command Line Properties false

  • SpringApplication.setAddCommandLineProperties(false)

test ํด๋”์— resources ๋งŒ๋“ค๊ธฐ

Project Structure > Module, Content Root์— text/resources ์—†๋‹ค๋ฉด ์ถ”๊ฐ€ํ•˜๊ธฐ

 

 

@ConfigurationProperties

ํƒ€์ž…-์„ธ์ดํ”„ ํ”„๋กœํผํ‹ฐ

์—ฌ๋Ÿฌ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋ฌถ์–ด์„œ ์ฝ์–ด์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

๋นˆ์œผ๋กœ ๋“ฑ๋กํ•ด์„œ ๋‹ค๋ฅธ ๋นˆ์— ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ๋‹ค.

์›๋ž˜ ConfigurationProperties์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด EnableConfigurationProperties(JueunProperties.class) ์„ค์ •ํ•ด์ฃผ์–ด์•ผ ํ•˜์ง€๋งŒ ์ด๋ฏธ ๋‚ด๋ถ€์ ์œผ๋กœ @EnableConfigurationProperties ๋“ฑ๋ก์ด ๋˜์–ด ์žˆ๋‹ค.
์šฐ๋ฆฌ๊ฐ€ ํ•ด์•ผ ํ•  ์ผ์€ @Component ๋˜๋Š” @Bean์„ ๋ถ™์—ฌ์ฃผ๋Š” ์ผ์ด๋‹ค.

 

@Component 

@Component
@ConfigurationProperties("jueun") // jueun์ด๋ผ๋Š” ํ‚ค ๊ฐ’์œผ๋กœ ํ”„๋กœํผํ‹ฐ ์‚ฌ์šฉ. getter/setter ํ•„์š”
public class JueunProperties {

    private String name;
    private int age;
    private String fullName;
    
    // getter/setter ์ƒ์„ฑ
    
}
jueun.name=JUEUN
jueun.age=${random.int(0,100)}
jueun.fullName=${jueun.name} Park
@Component
public class SampleRunner implements ApplicationRunner {

    @Autowired
    JueunProperties jueunProperties;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("=====================");
        System.out.println(jueunProperties.getName());
        System.out.println(jueunProperties.getAge());
        System.out.println(jueunProperties.getFullName());
        System.out.println("=====================");
    }
}

@Bean

Third-party Configuration ์‹œ ์‚ฌ์šฉํ•œ๋‹ค.

ํ”ํ•˜๊ฒŒ ์“ฐ์ด๋Š” case๋Š” ์•„๋‹ˆ๋‹ค.

@SpringBootApplication
public class Application {

    // Third-party Configuration
    // ์ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์•ˆ์— ์žˆ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ JAR ํŒŒ์ผ ์•ˆ์— ์žˆ๊ฑฐ๋‚˜ 
    // ์Šคํ”„๋ง์ด ์ œ๊ณตํ•˜๋Š” ํ”„๋กœํผํ‹ฐํด๋ž˜์Šค๋Š” @Component๋ฅผ ๋ชป ๋ถ™์ด๋‹ˆ๊นŒ @Bean์œผ๋กœ.
    @ConfigurationProperties("server")
    @Bean
    public ServerProperties serverProperties(){
        return new ServerProperties();
    }

    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(Application.class);
        app.setWebApplicationType(WebApplicationType.NONE);
        app.run(args);
    }

}

 Relaxed Binding

  • context-path
  • context_path
  • contextPath
  • CONTEXTPATH

Property Type Conversion

@DurationUnit์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•

@DurationUnit(ChronoUnit.SECONDS)
private Duration sessionTimeout = Duration.ofSeconds(30);
jueun.sessionTimeout=25

@DurationUnit์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  suffix๋กœ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•

private Duration sessionTimeout = Duration.ofSeconds(30);
jueun.sessionTimeout=25s

 

@Validated

 

<!-- dependency ์ถ”๊ฐ€ -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

JSR-303 ( @NotNull, @NotEmpty, @Size(min=0, max=100) )

@Component
@ConfigurationProperties("jueun") // jueun์ด๋ผ๋Š” ํ‚ค ๊ฐ’์œผ๋กœ ํ”„๋กœํผํ‹ฐ ์‚ฌ์šฉ. getter/setter ํ•„์š”
@Validated // Properties ์— ๋“ค์–ด์˜ค๋Š” ๊ฐ’๋“ค์„ ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ๋‹ค.
public class JueunProperties {

    @NotEmpty
    private String name;
    
}

๋น„์–ด์žˆ๋„๋ก ์„ค์ •ํ•ด์ฃผ๋ฉด

jueun.name=

Failure Analyzer๋กœ ์˜ˆ์˜๊ฒŒ ์˜ค๋ฅ˜๋ฅผ ์ถœ๋ ฅํ•ด์ค€๋‹ค.