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

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

beom seok Kim님의 프로필 이미지
beom seok Kim

작성한 질문수

토비의 스프링 부트 - 이해와 원리

커스톰 @Conditional

MyOnClassCondition에 있는 matches method의 Invoke 횟수

작성

·

90

0

 안녕하세요 토비님,

 

질문의 앞서, 좋은 강의자료 감사드립니다. 앞으로도 계속 꾸준히 만들어 주세요! ^^

 

혹시 MyOnClassCondition에 있는 matches method의 Invoke 횟수를 어떻게 예상하시나요?

 

저는 두번이라고 생각했는데요. "@ConditionalMyOnClass" annotation이 붙어있는 클래스가 두개 뿐이라서요.

 

그런데, 실제로 matches 안에서 출력을 해보니, 세번이 출력 되었습니다.

 

예상대로, TomcatWebServerConfig와 JettyWebConfigServerConfig를 각각 출력 했는데요. 그후에 한번 더 출력하더라구요. 마지막 출력은, 라이브러리에 포함된 것에 대한 config가 출력 됬습니다.

 

혹시 이유를 아시는지요?

답변 3

1

안녕하세요, 인프런 AI 인턴입니다. beom seok Kim님.

MyOnClassCondition의 matches 메서드가 세 번 호출되는 현상에 대해 문의해 주셨군요. 이는 스프링의 특정 동작 방식에 기인할 수 있습니다. 스프링은 애플리케이션 컨텍스트 초기화 시 여러 단계의 빈 정의 처리를 수행하며, 조건부 구성이 이 과정에서 여러 번 평가될 수 있습니다. 이로 인해 예상치 못한 호출이 발생할 수 있습니다.

스프링이 어떻게 빈들을 초기화하고 처리하는지 자세히 이해하기 위해서는, 빈 후처리기나 조건부 설정에 대한 스프링 공식 문서를 참조하는 것이 도움될 수 있습니다.

관련 질문과 자신의 코드에서 왜 이런 결과가 나왔는지 이해하는 데 도움이 될 수 있는 게시글 링크는 아래와 같습니다:

  1. BooleanCondition 동작 질문
    • 이 질문에서는 @Conditional 어노테이션의 동작 방식과 관련된 질문을 다루고 있으며, 여러 번 호출되는 원인에 대해 추가적인 설명을 확인할 수 있습니다.

위 링크를 통해 유사한 상황을 다룬 다른 사용자들과 지식 공유자님들의 답변을 참조하실 수 있습니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

0

beom seok Kim님의 프로필 이미지
beom seok Kim
질문자

와! 집적 확인해 주신다고 하니, 너무 감사드립니다!!

 

제가 회사 랩탑으로 연습을 해서(보안이슈), 다시 개인맥으로 toby님 repo를 clone후에 수정해서 올려 드립니다.

 

fork후 작업한 branch:

https://github.com/peter-kim-3d/helloboot/tree/test-count-invoking-in-matches

 

"커스톰 @conditional과 Condition 도입" commit으로 부터 수정했으며, MyOnClassCondition에서 matches 메서드 안에 print만 추가했습니다.

 

last commit:

https://github.com/peter-kim-3d/helloboot/commit/e0c0496d5a07c7b12e4230c76b5874781586b482

 

변경 된 코드:

public class MyOnClassCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        Map<String, Object> attrs = metadata.getAnnotationAttributes(ConditionalMyOnClass.class.getName());
        String value = (String) attrs.get("value");
        System.out.println("MyOnClassCondition: " + value);
        if(metadata instanceof AnnotationMetadata) {
            AnnotationMetadata annotationMetadata = (AnnotationMetadata) metadata;
            String className = annotationMetadata.getClassName();
            try {
                Class<?> aClass = Class.forName(className);
                System.out.println("------------>" + aClass.getName());
            } catch ( Exception e) {
                e.printStackTrace();
            }
        }
        return ClassUtils.isPresent(value, context.getClassLoader());
    }
}

 

출력(세번 호출):

MyOnClassCondition: org.apache.catalina.startup.Tomcat
------------>tobyspring.config.autoconfig.TomcatWebServerConfig
MyOnClassCondition: org.eclipse.jetty.server.Server
------------>tobyspring.config.autoconfig.JettyWebServerConfig
MyOnClassCondition: org.apache.catalina.startup.Tomcat
------------>tobyspring.config.autoconfig.TomcatWebServerConfig

0

beom seok Kim님의 프로필 이미지
beom seok Kim
질문자

와우 인프런 AI인턴 훌륭하네요. 저와 동일한 질문입니다. 그리고 토비님의 답변 잘 확인했습니다.

토비님의 프로필 이미지
토비
지식공유자

대략 추측은 했지만 어느 부분에서 한번 더 호출을 하는지 디버깅을 해보지는 못했는데 지금이라도 해보고 싶어지네요. 혹시 강의 어느 섹션 어떤 수업의 예제를 가지고 이걸 확인해보셨는지 알려주실 수 있으신가요? 혹은 이 현상을 출력하도록 작업하신 코드를 GitHub에 올려주시면 제가 받아서 추적을 해보겠습니다.

beom seok Kim님의 프로필 이미지
beom seok Kim

작성한 질문수

질문하기