[Spring 3.1 @Enable] 5. Configurer 패턴

자, 드디어 토비님의 @Enable* 발표 끝판 왕. Configurer 패턴을 볼차례다.

먼저, 확장 가능한 포인트를 인터페이스로 정의한다.

그리고 HelloConfig에서는 이 인퍼테이스 타입의 빈을 주입받아 사용하도록 코드를 변경한다.

EnableHello는 이제 더이상 별도의 속성이 필요없다.

그리고 AppConfig가 확장 포인트를 구현하도록 한다.

자, 이렇게 하면, AppConfig 자체도 @Configuration이니까 빈으로 등록될테고, 이 빈은 확장 가능한 포인트인 NameeConfigurer의 구현체니까, HelloConfig에 @Autowired로 주입이 되고, 그 안에서 확장 포인트가 호출되어, 빈의 특정 부위를 확장할 수 있는 형태가 된다. 바로 이 구조가 @EnableMVC의 구조와 같고, 이런 구조를 스프링에서는 Configurer 패턴이라고 부른다.

아.. 정말 스프링 DI의 끝을 모르겠다. 죽여준다.

마지막으로.. 감기 때문에 고생이신데도, 이렇게 멋지고 좋은 내용을 발표해주신 토비님,정말 감사합니다.

[Spring 3.1 @Enable] 4. @Import와 ImportBeanDefinitionRegistrar

이번에는 옵션에 따라 조금 더 복잡한 빈 조합이 필요한 경우라고 가정하겠습니다. 이런 경우 일일히 모든 경우에 해당하는 @Configuration을 만들기가 힘들기 때문에, 오히려 직접 코딩으로 옵션에 따라 빈을 등록하는 방법이 유용할 수도 있습니다.

이때는 ImportBeanDefinitionRegistrar 구현체를 만들고 이 구현체를 @Import에 설정하면됩니다.

이제는 type 같은 속성이 필요없으며, @Import에는 이 IBDR 구현체를 설정해주면 됩니다.

BeanDefinition을 만드는 API가 그렇게 아름답진 않은데, 빌더 패턴으로 BD를 만드는 API는 없는지 궁금해지네요. 없으면 만들어서 기증해볼까나.

옵션에 따라 등록해야 하는 빈이 매우 복잡하게 달라질 경우에 유용한 방법이 될 수 있겠습니다.

다시 조금 뒤로 돌아가서… 특정 빈 설정을 재사용할 때 그 빈 속성을 확장 가능한 형태로 만들고 싶다면 @Bean 메서드 오버라이딩이나, 템플릿 메서드 패턴을 이용하는 방법을 사용할 수 있었는데, ‘상속’을 이용하기 때문에 치명적인 단점(한가지 @Configuration 밖에 상속하지 못한다, @Overriding으로 주요 로직이 변경될 여지가 생긴다.)이 있었다.

그래서 @Import와 ImportAware, ImportSelector, ImportBeanDefinitionRegistrar를 활용하는 방법으로 빈 설정이나 속성을 확장하는 방법을 살펴봤는데, 이 방법 말고도 Configurer 패턴이라는 방법이 있다.

[Spring 3.1 @Enable] 3. @Import와 ImportSelector

이번에는 새로운 @Configuration을 하나 추가해보죠. 예를 들어, @EnableHello의 type이라는 속성값이 “korean”일때는 HelloKoreanConfig라는 @Configuration을 사용하고, type이 “english”일때는 HelloConfig를 사용하도록 하는거죠.

그리고 ImportSelector 인터페이스 구현체를 만들어서, 특정 애노테이션 속성에 따라 원하는 자바 설정 파일 이름을 리턴해 줍니다. 여기서 ‘왜 Class 타입이 아니라 String 타입의 배열을 리턴할까요?’라고 질문을 했었는데, 아마도 컴파일 시점에 참조할 수 없는 자바 설정도 동적으로 참조할 수 있도록 하려는 것이 아닌가 싶다는 답변을 들을 수 있었습니다.

이제는 @EnableHello 애노테이션에 ImportSelector 구현체에서 사용할 속성을 추가하고, @Import에다 HelloConfig가 아닌 ImportSelector 구현체를 설정합니다.

그럼 이제 AppConfig에 붙인 @EnableHello의 type 속성을 사용해서 전혀 다른 빈 집합이 등록되게 할 수 있습니다.

그런데, 만약에 옵션에 따라 너무도 다양한 빈 조합이 생긴다면, 이렇게 일일히 여러 빈 설정을 만드는 것도 상당히 번거로울 수 있습니다. 오히려 옵션에 따라 코딩으로 빈을 등록하는 방법도 필요할 수 있겠죠.