네번째 방법을 알아보자.

여기서 첫번째 XML을 이용한 annotation-config이 어떻게 @Configuration 클래스의 처리를 해주는지를 확인할 수 있다.

스프링2.0부터 도입된 XML 네임스페이스를 이용한 설정방법은 기존에 원시적인 오브젝트를 그대로 설정해줘야 하는 <bean> 뿐인 XML에 큰 변화를 주었다. 애플리케이션 컴포넌트가 아닌 컨테이너 설정을 위한 transaction, aop 같은 설정용 빈의 등록이나, JNDI와 같은 기술서비스의 등록은 보다 의미가 명확하게 노출되는 별도의 네임스페이스를 가지는 태그로 정의할 수 있게 되었다. XML이 줄어든 것도 가치가 있지만 그보다는 의도가 명확하게 드러난다는 점이 더 중요한 것이다.

이렇게 네임스페이스를 가지는 태그를 등록하면 스프링은 그 네임스페이스가 정의된 스키마를 찾아서 그 핸들러를 확인하고 그것을 호출한다. context 네임스페이스의 핸들러를 찾으려면 META-INF 밑의 spring.handlers 파일을 열어보면 된다.

이런 내용을 찾을 수 있다.

http\://www.springframework.org/schema/context=     org.springframework.context.config.ContextNamespaceHandler

그래서 처음 XML에서 썼던

<context:annotation-config />

를 스프링이 보고 위의 ContextNamespaceHandler를 불러주는 것이다. 태그에 정의된 애트리뷰트나 차일드 정보를 같이 넘져준다.

보통 핸들러들이 하는 일은 대부분 빈의 등록이다. 그냥 빈으로 등록해도 되는 것을 편하고 의미있게 태그로 만들어준 것이다. 더 나가서 태그 하나에 여러개의 빈을 등록하기도 한다.

 

ContextNamespaceHandler를 살펴보면 태그별로 다시 BeanDefinitionParser가 등록되어있어서 해당 tag의 처리를 담당하는 쪽으로 넘기게 된다. annotation-config은 AnnotationConfigBeanDefinitionParser여기서 처리. 이 코드를 보면 먼저 유틸 메소드를 호출해 빈의 정의를 받아온다. 그리고 이걸 컴포넌트로 구성해서 등록한다. 중첩 태그로 구성되어있을 경우 등등을 고려한 처리등이 있다.

중요한 것은 이 태그에 의해서 정의되는 빈들이 있다는 것이다.

// Obtain bean definitions for all relevant BeanPostProcessors.
Set<BeanDefinitionHolder> processorDefinitions =
       AnnotationConfigUtils.registerAnnotationConfigProcessors(parserContext.getRegistry(), source);

이 코드를 보면 AnnotationConfigUtils.registerAnnotationConfigProcessors를 불러서 그 등록작업을 처리하게 한다.

그 안을 보면 기본적으로 4개의 빈을 등록하게 되어있다. JPA용도 있는데 이건 특별하니까 일단 무시.

4개를 살펴보면 이렇다.

  • ConfigurationClassPostProcessor
  • AutowiredAnnotationBeanPostProcessor
  • RequiredAnnotationBeanPostProcessor
  • CommonAnnotationBeanPostProcessor

즉 annotation-config 태그 하나를 보고 위의 4개의 PostProcessor 빈을 등록해주는 것이다.

바로 이중의 첫번째가 우리가 직접 써봤던 바로 그 ConfigurationClassPostProcessor이다. 그래서 결국 annotation-config만 해줘도 ConfigurationClassPostProcessor가 등록이 되기 때문에 애플리케이션 컨텍스트에서 자동으로 저 BFPP를 적용해주게 되는 것이다.

보너스로 나머지도 보면 @Autowired를 담당하는 AutowiredAnnotationBeanPostProcessor, @Required를 담당하는 RequiredAnnotationBeanPostProcessor, 그리고 JSR-250 표준애노테이션을 담당하는 CommonAnnotationBeanPostProcessor가 각각 등록이 되서 적용되는 것이다.

기존에 2.5에서는 이 세가지만 있었지만 3.0에서 ConfigurationClassPostProcessor 추가 된 것이라고 보면 된다.

 

그렇다면 만약 @Autowired 같은 것은 필요없고 나는 자바클래스 설정인 @Configuration만 쓰고 싶은데 XML로 정의하고 싶다면 어쩔까? 그럼 그냥 직접 저 PostProcessor를 등록해주면 된다.

<context:annotation-config />

을 빼고

<bean class="org.springframework.context.annotation.ConfigurationClassPostProcessor" />

만 넣어도 된다는 것이다. 스프링의 모든 네임스페이스를 쓴 태그들은 결국 직접적인 빈의 등록으로 다 대치할 수 있다. 그 안에서 이상한 짓만 하지 않는다면.

 

이제 왜 XML의 설정으로 @Configuration처리가 됐는지 다 알아봤다.

내가 쓴 4번째 방법은 이 handler 내부에서 썼던 AnnotationConfigUtils.registerAnnotationConfigProcessors 유틸리티 메소드를 사용해본 것이다. 이 등록부분을 구지 Utils에 따로 둔 이유는, 다른 곳에서도 사용하기 때문이다. 테스트에서 특히 많이 사용하고.

 

그럼 이걸 호출해서 PostProcessor를 등록해도 된다는 것.

GenericApplicationContext ctx = new GenericApplicationContext();
ctx.registerBeanDefinition("config", new RootBeanDefinition(Config.class));

AC만드는 것은 똑같고 대신 직접 PP를 등록 안하고 위의 메소드를 이용한다.

AnnotationConfigUtils.registerAnnotationConfigProcessors(ctx, null);

그리고 AC refresh() 해주면 끝.

ctx.refresh();       
String hello = ctx.getBean("hello", String.class);
assertThat(hello, is("Hello"));

 

분석 끝.

 

@Configuration의 XML을 이용한 사용방법 하나만 그 동작원리를 찾아보려고 하면 이만큼 많은 것을 공부할 수 있다. 이런게 스프링을 연구하는 재미가 아닐까.

이거 하나만 제대로 연구해도 이런 보너스가.

  • BeanFactoryPostProcessor 은 무슨 짓을 하는가.
  • BeanDefinition로 빈이 등록되는 방법.
  • BeanFactory + ApplicationContext의 관계와  인터페이스와 클래스 계층구조.
  • Namespace/Handler 동작원리.

Related posts:

  1. InsideSpring (1) Annotated Factory Method (@Configuration)을 쓰는 4가지 방법 (1)
  2. InsideSpring (1) Annotated Factory Method (@Configuration)을 쓰는 4가지 방법 (2)
  3. 테스트 할 수 없는 것을 테스트 하기. Spring ROO와 static method mocking.
  4. InsideSpring (3) 스프링 밖에서 WebApplicationContext에 접근하기
  5. InsideSpring (4) 빈 스캐너는 클래스를 로딩할까?
  6. InsideSpring (2) AutoProxyCreator는 Pointcut의 ClassFilter만 사용하지 않는다
  7. Spring 3.0 (33) JavaConfig의 통합과 변신. 메타-빈(meta-bean) 개념의 등장.
  8. DispatcherServlet의 디폴트 대체(fallback) 전략
  9. Inside Spring (5) PropertyPlaceholderConfigurer를 @Bean으로 정의해서는 안되는 이유
  10. 스프링 3.1 (4) Static @Bean 메소드
  11. Spring 3.0.1 mvc:annotation-driven 이 몰래 하는 짓
  12. 스프링 빈의 이름은 한글로 지어도 된다
  13. S1A 2008 셋째날 – Spring JavaConfig
  14. Spring 3.0 (60) 클래스패스 리소스를 지정할 때 주의사항과 팁
  15. Spring 2.0의 XML확장기능 (1)

Facebook comments:

to “InsideSpring (1) Annotated Factory Method (@Configuration)을 쓰는 4가지 방법 (3)”

  1. 좋은글 잘 읽었습니다. 왜루가 설정이 약간 다를까 했는데, 좋은 설명이 되었습니다.^^*

  2. When I originally left a comment I seem to have clicked on the -Notify me when
    new comments are added- checkbox and from now on every time a comment is added I
    receive 4 emails with the same comment. Perhaps there is an easy method
    you can remove me from that service? Thanks a lot!

    Feel free to surf to my site online payday

  3. Have A Peek At These Guys

  4. Why Not Check Here
    [url=http://www.jnxmjz.com/member/albumiedit.php?/refrigerator-egg-holder-get-good-quality-products-with-a-good-price-on-these-products-2013.html]refrigerator egg holder-Get good quality products with a good price on these products 2013[/url]
    refrigerator egg holder-Get good quality products with a good price on these products 2013

  5. Try this out
    [url=http://www.hunjia100.com/member/introducel.php?/japan-lingzhi-2-day-diet-side-effects-meizitang-on-discount.html]japan lingzhi 2 day diet side effects-meizitang-on discount[/url]
    japan lingzhi 2 day diet side effects-meizitang-on discount

  6. Navigate To THIS WebSite
    [url=http://fakebootsonsale.com]fake ugg boots for sale[/url]
    fake ugg boots for sale

  7. Navigate To THIS WebSite
    [url=http://cheapbaileybuttonoutlet.com]mini uggs[/url]
    mini uggs

  8. thank you for share!

Leave a Reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

© 2017 Toby's Epril Suffusion theme by Sayontan Sinha