우리는 스프링의 매직을 통해 간단한 어노테이션 선언 만으로 Bean 을 등록 하곤 했다.
@Component
public class Foo {}
실제로는 어떤 Bean 이름으로 등록될까? 🤔
먼저 ClassPathBeanDefinitionScanner 라는 클래스가 AnnotationBeanNameGenerator 인스턴스 를 정적으로 선언 한다.
ClassPathBeanDefinitionScanner 가 doScan 을 통해 base packages 내의 어노테이션 빈 정의를 스캔한다.
이 과정에서 String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
을 통해 빈 이름을 결정 한다.
generateBeanName 는 빈 이름을 어떻게 결정 할까?
AnnotationBeanNameGenerator 클래스를 찾아보면 설명에 답이 나와 있다.
com.xyz.FooServiceImpl
를 fooServiceImpl
으로 리턴 한다고 한다.
여기에서 생기는 문제점은 바로 떠오르기 쉽다.
com.naver.FooServiceImpl
와 com.kakao.FooServiceImpl
를 각각 빈으로 등록 한다면 충돌이 발생 할 것이다.
BeanNameGenerator 인터페이스를 구현하여 나만의 커스텀 빈 제네레이터를 만드는 것이다.
public class CustomBeanNameGenerator implements BeanNameGenerator { ... }
어플리케이션 시작 클래스에 커스텀 빈 제네레이터를 적용하면 끝!
@SpringBootApplication
@ComponentScan(nameGenerator = CustomBeanNameGenerator.class)
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}