인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

yamyam_Y님의 프로필 이미지
yamyam_Y

작성한 질문수

스프링 부트 - 핵심 원리와 활용

@Conditional - 다양한 기능

conditional 적용 문의

작성

·

558

0

안녕하세요,

자동구성 설정 부분에서 예시로 config파일에 memorycontroller를 빈으로 설정 후 conditional 동작 여부 확인하는 부분을 학습하던 중 궁금한 점이 생겨서 문의드립니다.

빈으로 등록한 controller에도 conditionalOnMissingBean을 적용해서 원하는 controller만 빈으로 등록되게 할수 있을까요?

===========================

동작을 예상한 시나리오는 Memory2Controller가 빈으로 등록이 되어서 memory2 로그가 찍히는 걸 예상했는데

설정이 잘못된건지 잘모르겠습니다.

아니면 controller에는 conditional적용을 할순없는걸까요?

답변 1

1

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. HY_Purple님

전체 프로젝트를 압축해서 구글 드라이브로 공유해서 링크를 남겨주세요.

구글 드라이브 업로드 방법은 다음을 참고해주세요.

https://bit.ly/3fX6ygx

주의: 업로드시 링크에 있는 권한 문제 꼭 확인해주세요

추가로 다음 내용도 코멘트 부탁드립니다.

1. 실행 방법을 알려주세요.

2. 어떻게 문제를 확인할 수 있는지 자세한 설명을 남겨주세요.

감사합니다.

yamyam_Y님의 프로필 이미지
yamyam_Y
질문자

업로드 프로젝트 예시 입니다.

https://drive.google.com/file/d/1XwWWtDrKTfHq2nMtN5wpjpbaUI1ovS1y/view?usp=sharing

 

  1. build.gradle로 프로젝트를 실행 하시면 됩니다.

  2. ConditionalOnBean을 사용하여 Controller 조건부 빈 등록을 하려합니다.

    조건) MemoryController, CustomMemoryController는 같은 requestmapping을 사용합니다.

    • DefaultController 인터페이스를 구현하는 MemoryController, CustomMemoryController 두개가 있습니다.

    • 기본적으로 CustomMemoryController실행 되지만, CustomMemoryController가 빈 등록이 되지않았다는 가정하에

      ConditionalOnMissingBean(DefaultController.class)로 체크하여 defaultcontroller 빈 이 없을 경우 MemoryController가 동작 할수 있는 방법이 있을까요?

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. yamyam_Y님

현재 TestApplication은 com.example.test 패키지에 위치하고 있습니다.

여기에는 @SpringBootApplication 애노테이션이 있는데요. 이 애노테이션은 현재 패키지 위치부터 그 하위까지 모두 컴포넌트 스캔을 해버립니다.

package com.example.test;

@SpringBootApplication
public class TestApplication {

    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class, args);
    }

}

따라서 이렇게 되면

com.example.test.memory 패키지 하위에 있는 CustomMemoryController, MemoryController 둘다 @Controller 애노테이션이 있으므로 컴포넌트 스캔의 대상이 되어서 둘다 스프링 빈으로 이미 등록이 되어버립니다.

이미 컴포넌트 스캔으로 둘다 등록해버렸기 때문에 사용하신 다음 기능은 효과가 없습니다. @ConditionalOnMissingBean(DefaultMemoryController.class)

해결 방안으로는 컨트롤러를 컴포넌트 스캔하지 않도록 다음과 같이 컴포넌트 스캔 위치를 명확하게 지정해주세요.

@SpringBootApplication(scanBasePackages = "com.example.test.config")

그리고 다음과 같이 설정해서 사용하시면 됩니다.

package com.example.test.config;

@Configuration
public class MemoryConfig {

    @Bean
    @ConditionalOnMissingBean(DefaultMemoryController.class)
    public DefaultMemoryController memoryController() {
        System.out.println("MemoryConfig.memoryController");
        return new MemoryController(memoryFinder());
    }

    @Bean
    public MemoryFinder memoryFinder() {
        return new MemoryFinder();
    }
}
package com.example.test.config;

@Configuration
public class CustomControllerConfig {

    @Bean
    public CustomMemoryController customMemoryController(MemoryFinder memoryFinder) {
        System.out.println("CustomControllerConfig.customMemoryController");
        return new CustomMemoryController(memoryFinder);
    }

}

감사합니다.

yamyam_Y님의 프로필 이미지
yamyam_Y
질문자

이해했습니다,,! 감사합니다🙂

yamyam_Y님의 프로필 이미지
yamyam_Y

작성한 질문수

질문하기