본문 바로가기

Computer/Java

ReactiveMongoTemplate & SpEL BeanResolver 오류 해결

ReactiveMongoTemplate & SpEL BeanResolver 오류 해결

@Document("SCORECARD_#{@applicationProperties.phase}") 와 같이 컬렉션 이름을 SpEL로 지정하면 문법상 문제는 없지만, 직접 new ReactiveMongoTemplate(factory) 로 템플릿을 만들면 다음과 같은 예외를 흔히 만납니다.

org.springframework.expression.spel.SpelEvaluationException
EL1057E: No bean resolver registered in the context to resolve access to bean 'applicationProperties'

1. Spring Boot가 자동으로 해 주는 일

  1. MongoMappingContext 인스턴스 생성
  2. MongoMappingContext#setApplicationContext(…) 호출
     → BeanResolver 등록
  3. MappingMongoConverter 생성
     → SpEL 평가 시 @beanName 탐색 가능
  4. ReactiveMongoTemplate 생성
Point – BeanResolver가 없으면 SpEL은 @applicationProperties 같은 Bean을 찾을 수 없습니다.

2. 직접 템플릿을 만들면?

@Bean
fun reactiveMongoTemplate(factory: ReactiveMongoDatabaseFactory) =
    ReactiveMongoTemplate(factory)   // ⚠️ Converter / Context 누락!
  • Converter와 MappingContext를 건너뛰므로 BeanResolver가 설정되지 않습니다.
  • 결과적으로 SpEL이 Bean 이름을 해석할 수 없고, 위 예외가 발생합니다.

3. 해결책

(A) Spring Boot 자동구성 그대로 사용

spring.data.mongodb.uri, databaseapplication.yml에 설정하고 Mongo 관련 Bean을 직접 정의하지 않는 방법이 가장 간단합니다.

(B) 수동 설정 시 MappingMongoConverter 명시

@Configuration
class MongoConfiguration {

    @Bean
    fun mongoClient(cfg: ConfigProperties): MongoClient =
        MongoClients.create(cfg.mongodb.uri)

    @Bean
    fun mongoDbFactory(cfg: ConfigProperties, client: MongoClient): ReactiveMongoDatabaseFactory =
        SimpleReactiveMongoDatabaseFactory(client, cfg.mongodb.database)

    @Bean
    fun mappingMongoConverter(
        ctx: ApplicationContext,
        conversions: MongoCustomConversions
    ): MappingMongoConverter {
        val mappingCtx = MongoMappingContext().apply {
            setApplicationContext(ctx)      // ★ BeanResolver 주입
        }
        return MappingMongoConverter(NoOpDbRefResolver.INSTANCE, mappingCtx).apply {
            setCustomConversions(conversions)
            afterPropertiesSet()
        }
    }

    @Bean
    fun reactiveMongoTemplate(
        factory: ReactiveMongoDatabaseFactory,
        converter: MappingMongoConverter
    ) = ReactiveMongoTemplate(factory, converter)
}
결과 – BeanResolver가 연결되어 SpEL이 @applicationProperties.phase를 정상적으로 평가합니다.

TL;DR

  • SpEL 실패의 진짜 이유는 MappingMongoConverter & Context에 BeanResolver가 없기 때문.
  • Spring Boot 자동구성을 쓰거나, 수동 설정 시 MongoMappingContext#setApplicationContext()를 호출해 BeanResolver를 주입하자.

'Computer > Java' 카테고리의 다른 글

[JAVA] 수정자 ( modifier )  (0) 2015.03.09