문제 발생 상황은 다음과 같다.
- Spring Boot AutoConfiguration으로 개발
- ConfiguartionProperties를 사용
- AutoConfiguration에서 ConfiguartionProperties를 생성자 또는 @PostConstruct에서 호출하여 추가 작업을 처리
- 다른 Configuration에서 해당 properties를 사용하면 3번 작업이 수행되지 않은 상태로 ConfigurationProperties가 넘어와서 문제가 발생 (로그로 확인해보면 이 후에 수행 되는 것을 확인함)
해당 상황의 간단한 코드는 다음과 같다.
@Configuration
@EnableConfigurationProperties(TestProperties.class)
public class AConfiguration {
@Autowired
private TestProperties testProperties;
@PostConstruct
public void postConstruct() {
// testProperties의 값 들을 변경 처리
}
}
@ConfigurationProperties(prefix = "test-prop")
public class TestProperties {
// 값 들을 설정
}
@Configuration
public class BConfiguration {
// 여기서 TestProperties를 가져다가 사용 (@Autowired 나 method parameter로 사용)
}
AutoConfiguration의 호출
Spring Boot AutoConfiguration을 사용할 때 spring.factories에 등록된 EnableAutoConfiguration 목록을 호출하여 사용하는데 이때 순서는 참조된 autoConfiguration 관계에 따라 정렬이 되어 사용된다.
관계가 명확하지 않은 경우 @AutoConfigureAfter나 @AutoConfigureBefore 를 통해 순서 설정을 하는 방법도 있다.
빈(Bean) 등록 순서
@Configuration 로 선언된 class 또한 @Component로 등록되는 빈이다.
그런데 @Configuration class 내에 @Bean으로 선언된 여러 method에 의해 생성된 빈은 각 빈들의 연관 관계에 따라 생성 순서가 정해지지만 @Configuration으로 지정한 AConfiguration이나 BConfiguration은 직접 해당 빈을 호출하여 사용하는 부분이 보통 없기 때문에 해당 빈이 생성되는 시점은 한참 뒤가 된다.
@Configuration class 안에 @Bean으로 선언된 여러 method에 의해 생성된 빈들과 autoConfiguration class에 의해 만들어진 빈은 아무 연관 관계가 없기 때문이다.
정리하면 순서는 다음과 같다.
- TestProperties class의 bean이 생성됨
- 여러 @Configuaration class 내에 선언된 @Bean method의 bean이 연관 관계에 따라 순서대로 생성됨
- @Configuration class의 bean이 생성됨
따라서 위에 처럼 AConfiguration에 설정된 @PostConstruct는 가장 나중에 동작한다.
만약 properties의 값을 후처리하고 싶다면 아래처럼 InitializingBean을 구현한다.
@ConfigurationProperties("test-prop")
public class TestProperties implements InitializingBean {
// 값 들을 설정
@Override
public void afterPropertiesSet() throws Exception {
// testProperties의 값 들을 변경 처리
}
}
이렇게 하면 testProperties class의 bean이 생성되는 시점 이후 afterPropertiesSet 후처리가 먼저 동작하여 의도한 대로 변경된 값을 사용할 수 있게 된다.
따라서 @ConditionalOnBean을 @Configuration class에 같이 사용하는 경우 @AutoConfiguration하는 class 자체 빈을 조건으로 사용하지 말아야 한다.
호출 순서가 늦기 때문에 조건 체크 시 문제가 발생할 수 있다.
'Study > Java' 카테고리의 다른 글
RestTemplate 응답 log 확인하기 (0) | 2019.06.20 |
---|---|
Asciidoc 문서 작성을 위한 프로젝트 경로 설정 팁 (0) | 2019.06.19 |
Eclipse (STS) 메모리 설정 이후 응답 없음 현상 (0) | 2019.06.17 |
Spring Rest Docs 사용해보기 (0) | 2019.06.14 |
Spring Boot 전역 에러 처리 (0) | 2019.04.30 |
Eclipse debug view의 Variables에 Error 가 표시되는 경우 (0) | 2019.04.19 |
Eclipse Package Explorer 에서 Maven Dependencies 정렬하기 (0) | 2019.04.18 |
Spring Boot AutoConfigurtaion java.io.FileNotFoundException: class path resource [.class] cannot be opened because it does not exist 에러 (0) | 2019.04.03 |
Spring Boot AutoConfiguration 개발하기 (0) | 2019.03.28 |
Jasypt 암복호화 하기 (1) | 2019.03.01 |