Heart's Develop Inside (WP)

Heart's Develop Blog in WordPress.com

Mybatis-Spring 의 MapperScannerConfigurer 를 통해 Spring 공부하기

leave a comment »

현재 진행 중인 프로젝트에서 MapperScannerConfigurer 를 사용하면서 겪은 이슈(정확히는 co-work 하는 팀원 분이 고생하시면서 겪은 이슈) 들을 통해 Spring 내부에 대해 공부해야 할 필요성을 깨닫게 되어 공유합니다.

미리 겪은 이슈에 대해 간단히 설명드리면, Spring 설정을 Java code(@Configuration 클래스)로 변경하면서 @Bean 을 통해 MapperScannerConfigurer 를 등록하게 되었는데, 변경 후에 MapperScannerConfigurer 가 정상적으로 동작하지 않는 이슈가 있었습니다.

문제의 MapperScannerConfigurer 클래스를 소개합니다.

http://mybatis.github.io/spring/apidocs/reference/org/mybatis/spring/mapper/MapperScannerConfigurer.html

Class Overview 를 보시면, 이 클래스는 Mybatis-spring 1.0.1 까지는 BeanFactoryPostProcessor 를 구현하고 있었지만, 1.0.2 에서 BeanDefinitionRegistryPostProcessor 를 구현하고 있습니다.
(BeanFactoryPostProcessor 를 잘 모르신다면 글 맨 아래에 있는 Toby 님의 문서를 먼저 읽고 되돌아오시는 것이 이후 이어질 내용들을 이해하시기에 수월합니다)

아래 이슈를 보시면 변화의 원인을 알 수 있습니다.

https://jira.springsource.org/browse/SPR-8269?focusedCommentId=66210&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-66210

comment 내용 중 관련 내용을 가져왔습니다.

Osvaldas – as an additional note, it looks like MapperScannerConfigurer should really be a BeanDefinitionRegistryPostProcessor instead of a BeanFactoryPostProcessor. The reason for this is that it actually registers additional beans (through scanning) as opposed to simply post-processing additional bean definitions. (이하 생략)

BeanDefinitionRegistryPostProcessor (Spring 3.0.1 에서 도입)는 BeanFactoryPostProcessor 를 상속한 인터페이스입니다.
사용 용도를 구분하기 위해 추가된 것으로 보이는데요.
BeanFactoryPostProcessor 는 미리 정의된 bean 정의에 대한 후처리를 주로 담당하구요.(대표적인 것이 PropertyPlaceholderConfigurer 입니다)
BeanDefinitionRegistryPostProcessor 는 bean 들의 정의를 “추가로” 등록하는 기능을 담당하고 있습니다.
(Custom BeanDefinitionRegistryPostProcessor 의 예제를 링크합니다)

문제는, @Configuration 클래스는 BeanDefinitionRegistryPostProcessor (BDRPP) 에 의해 로드되는데, BDRPP 동작 중에 BeanDefinitionRegistryPostProcessor 가 발견되어도  postProcessBeanDefinitionRegistry() 메소드가 호출되지 않는 이슈가  있습니다.
(관련 이슈 : BeanDefinitionRegistryPostProcessor registered via @Bean will not be invoked)

이에 덧붙여, AnnotationConfigApplicationContext를 사용할 경우 @Configuration 클래스 내에 BeanFactoryPostProcessor 가 @Bean 으로 등록되면, 의 @Configuration 클래스에 정의된 기본 BeanFactoryPostProcessor 관련 동작이 수행되지 않는(@Autowired 에 injection 이 되지 않음, @PostConstruct 메소드가 호출되지 않음 등) 이슈가 있습니다. (SPR-8269 이슈가 발행된 원인입니다)

이런 이슈들을 해결하기 위해 Spring 3.1 에서는 @Enable* annotation 이 도입되었고, Mybatis-spring 또한 @MapperScan 을 사용할 수 있게 기능이 추가되었습니다.
(처음에는 @EnableMyBatisMapperScanner(@Enable* 명명을 따랐다) 라고 명명했다가 가독성을 이유로 변경되었습니다 : Mybatis-spring 의 commit log  참조)

현재의 프로젝트도 @MapperScan 을 사용하여 해결했습니다.

ps. DataSource 를 여러 개 사용하는 경우 클래스에 annotation 이 중복 지정되지 않기 때문에 @Configuration 클래스에 @MapperScan 을 여러 번 사용할 수 없어서 추가 방법을 고민해야 합니다.

ps2. AbstractApplicationContext.invokeBeanFactoryPostProcessors() 의 Code Block 을 설명한 포스트가 있어서 링크합니다. 인용된 Code Block 은 BeanFactoryPostProcessor 와 BeanDefinitionRegistryPostProcessor 가 어떻게 bean 정의에 활용되는지 설명해 주고 있습니다.

ps3. Toby 님께서 만드신 Spring 3.1 @Enable 사용 방법 설명 문서를 찾았는데 자료가 아주 좋은 것 같아 덧붙입니다. 이것만 보아도 Spring 의 bean 초기화 과정의 많은 내용들을 짚고 갈 수 있을 것 같네요.

Advertisements

Written by kabhwan

2013년 7월 4일 , 시간: 1:17 오전

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

%s에 연결하는 중

%d 블로거가 이것을 좋아합니다: