예제소스는 깃허브에 있습니다.
스프링 빈의 생명주기에 BeanNameAware 의 setBeanName 을 호출한다는 그림이 있다.
여태 일해오면서 BeanNameAware에 대해 의식하고 개발한 적은 없는데,
궁금해서 찾아보았다.
생명주기 그림상으론 setBeanName 가 빈 이름을 셋팅한다는 것 처럼 보이는데, 사실 그건 아니고 빈을 만들 시점에 BeanNameAware 인터페이스를 상속하면 setBeanName 메서드를 통해 이름을 얻어올 수가 있다.
public interface BeanNameAware extends Aware {
void setBeanName(String name);
}
사용 예시
@Component
class CustomBean1 : BeanNameAware {
override fun setBeanName(name: String) {
println("bean name: $name") // customBean1
}
}
@Component("cuscusbean")
class CustomBean2 : BeanNameAware {
override fun setBeanName(name: String) {
println("bean name: $name") // cuscusbean
}
}
Aware 인터페이스는 언제 호출되는지 찾아보는 것은 어렵지 않았다. 메서드를 타고 들어가보면 된다.
아래 코드처럼 Aware 마커인터페이스를 구분하고, 하위의 Aware들을 차례대로 invoke 해준다.
AbstractAutowireCapableBeanFactory.java
위 코드를 보면 어딘가에서 beanName을 계속 가져오는데.. 빈 생명주기 안에서 언제 빈 이름을 셋팅하는지가 궁금해졌다.
대략 순서는 아래와 같다.
BeanName 셋팅 순서
1. 각종 방식의 빈 설정을 통해 BeanDefinition 생성 (어노테이션 기반, xml 기반, bean config 기반 등..)
2. BeanNameGenerator에서 BeanDefinition 을 기반으로 빈 이름 생성
- Component 에 빈 이름을 설정한 경우는 그쪽에서 빈 이름을 가져온다.
- 빈 이름을 따로 정하지 않은 경우 default bean name을 만들게 되는데 클래스 이름의 decapitalize를 하게 된다. Introspector.decapitalize(shortClassName);
어노테이션에 빈 이름을 지정하지 않은 경우 (ex. @Component)
AnnotationBeanNameGenerator.java
Introspector.java
어노테이션에 빈 이름을 지정한 경우 (ex. @Component("cuscusbean"))
AnnotationBeanNameGenerator.java
댓글