파란하늘의 지식창고
반응형

문제 발생 상황은 다음과 같다.

  1. Spring Boot AutoConfiguration으로 개발
  2. ConfiguartionProperties를 사용
  3. AutoConfiguration에서 ConfiguartionProperties를 생성자 또는 @PostConstruct에서 호출하여 추가 작업을 처리
  4. 다른 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에 의해 만들어진 빈은 아무 연관 관계가 없기 때문이다.

정리하면 순서는 다음과 같다.

  1. TestProperties class의 bean이 생성됨
  2. 여러 @Configuaration class 내에 선언된 @Bean method의 bean이 연관 관계에 따라 순서대로 생성됨
  3. @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 자체 빈을 조건으로 사용하지 말아야 한다.

호출 순서가 늦기 때문에 조건 체크 시 문제가 발생할 수 있다.

반응형
profile

파란하늘의 지식창고

@Bluesky_

도움이 되었다면 광고를 클릭해주세요