티스토리 뷰

기본적으로 Spring Boot에서는 application.properties라는 파일을 설정 파일로 사용한다. (YML도 사용하기도 한다.)

설정 파일을 Application 안팎에 둘 수 있는데, 저 녀석이 Spring Boot가 Application을 구동할 때 자동으로 로딩하는 파일 이름이다. 여기에 key - value 형태로 값을 정의하면 Application에서 참조하여 사용할 수 있게 된다.

 

여기서 중요한 점은 property는 우선순위에 따라서 그 값이 overwrite될 수 있다는 점이다. 

 

프로퍼티 우선 순위

1. 유저 홈 디렉토리에 있는 spring-boot-dev-tools.properties
2. 테스트에 있는 @TestPropertySource
3. @SpringBootTest 애노테이션의 properties 애트리뷰트
4. 커맨드 라인 아규먼트
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
14. JAR 밖에 있는 application properties
15. JAR 안에 있는 application properties
16. @PropertySource
17. 기본 프로퍼티 (SpringApplication.setDefaultProperties)

지금부터 이 property를 사용하는 방법을 알아보자. 가장 기본적인 방법이 바로 위처럼 @Value 를 사용하는 방법이다. 

# application.properties

chany.name = chany
@Component
public class SampleRunner implements ApplicationRunner {

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

}

@Value에 properties에 입력한 key값을 입력해서 해당 value를 가져올 수 있다. 그리고 Test의 경우에는 Enviroment 객체를 통해서 가져올 수 있다.

 

@RunWith(SpringRunner.class)
@SpringBootTest
class SpringInitApplicationTest {

    @Autowired
    Environment environment;

    @Test
    public void contextLoad() {
        assertThat(environment.getProperty("chany.name"))
                .isEqualTo("Chang");
    }
}

 

Test에서만 사용하는 properties를 추가해서 사용하고자 할 때는 test 하위에 resources/application.properties 를 넣어두고, 프로젝트 설정에 해당 폴더를 test resource folder를 설정해주면 테스트용 properties 파일을 사용할 수 있다.

 

그러나, 주의해야할 점이 기본적으로 test 코드를 빌드할 때 src/main에 있는 모든 코드를 빌드하고 classpath에 넣은 뒤에 test 하위의 코드를 빌드하기 때문에 mainproperties 파일이 testproperties로 overwirte되어 버린다.

 

예를 들어,

 

# main application.properties

chany.name = chany
chany.age = ${random.int(0,100)}	(Random값 받을 때 사용가능)

 

# test application.properties
chany.name = chang

 

두 property가 있을 때, Test에서는 실제로 chany.namevalue로는 chang이 나오게 된다.

 

또 한 가지 번거로운 문제가 발생하는데 지금 위처럼 Main Properties에 있는 값이 Test에는 없는 경우에 Error가 발생하게 된다.

(위에도 언급했던 것처럼 main 아래의 모든 코드를 빌드하고 test 아래의 코드를 빌드할 때 main의 application.properties에 있는 값이 test의 application.properties에 없기 때문)

 

이러한 문제를 해결하기 위해서는, @TestPropertySource 를 추가하여 해결할 수 있다. 두 파일이 충돌하여 생기는 문제는 우선 Testproperties 파일을 삭제하고, 테스트에서 어떤 특정 값을 변경하고 싶을 때 아래처럼 properties 안에 값을 재정의하여 줄 수 있다.

 

@TestPropertySource(properties = "chany.name=chang")
class SpringInitApplicationTest {

    @Autowired
    Environment environment;

    @Test
    public void contextLoad() {
        assertThat(environment.getProperty("chany.name"))
                .isEqualTo("Chang");
    }
}

 

그러나 만약 그 값이 너무 많을 때는 파일로 관리를 할 수 있는데 이런 경우에는 @TestPropertySource 에 location을 명시하여 주면 된다. classpath기준으로 path를 입력하여 주면 해당 properties 파일의 값을 가져온다. (application.properties와는 다른 이름으로!) 

 

@RunWith(SpringRunner.class)
@SpringBootTest
@TestPropertySource(locations = "classpath:/test.properties")
class SpringInitApplicationTest {

    ...
}

이번에는 application.properties에서 같은 key로 시작하는 값들을 하나로 묶어서 Bean으로 등록하는 방법을 알아보자. 

 

@Component
@ConfigurationProperties("chany")
public class ChanyProperties {

    String name;
    int age;
    String fullName;

    getter / setter …
}

 

원래는 @EnableConfigurationProperties 을 메인 클래스에 해당 properties 클래스를 직접 Bean으로 등록하여 줘야 하지만, 기본으로 등록되어 있기 때문에 properties 클래스에 @Component 를 달아 Bean으로 등록되도록 해주면 된다.

 

위처럼 해당 값을 가져올 class를 하나 생성하고 @ConfigurationProperties 에 공통으로 등장하는 key값을 명시하여 주면 된다. 그리고 properties 파일 작성 시 자동완성 관련 기능을 제공하는 configuration-processor를 의존성에 추가한다.

 

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

 

이렇게 설정한 뒤에 아래처럼 주입받아서 사용할 수 있다

 

@Component
public class SampleRunner implements ApplicationRunner {

    @Autowired
    private ChanyProperties chanyProperties;

    @Override
    public void run(ApplicationArguments args) throws Exception {

        System.out.println("===================================");
        System.out.println(hello);
        System.out.println(chanyProperties.getFullName());
        System.out.println(chanyProperties.getName());
        System.out.println("===================================");

    }
}

마지막으로 property에 들어오는 값을 검증하는 방법을 알아보자. 

 

@Validated 를 사용하면 Properties class에서 특정 field의 값을 검증할 수 있다. 가령, 위의 예시를 그대로 가져와서 적용하면,

 

@Component
@ConfigurationProperties("chany")
@Validated
public class ChanyProperties {

    @NotEmpty
    String name;
    int age;
    String fullName;

    getter / setter …
}

 

@NotEmpty 와 같은 검증을 할 수 있다

 

검증 가능한 여러 Annotation

 


@ 출처

 

 스프링 부트 개념과 활용 - inflearn, by 백기선님

댓글
링크
최근에 올라온 글
Total
Today
Yesterday