네번째 방법을 알아보자.

여기서 첫번째 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. You actually reported that perfectly. ampicillin

  2. we like to honor several other web internet sites on the net, even if they arent linked to us, by linking to them. Underneath are some webpages worth checking out

  3. Wow that was strange. I just wrote an incredibly long comment but after I clicked submit my comment didn’t show up. Grrrr… well I’m not writing all that over again. Regardless, just wanted to say superb blog!|

  4. You actually stated it wonderfully. 60mg Prozac No Prescription Cheap

  5. The details mentioned within the post are some of the most beneficial readily available

  6. You suggested that very well. buy cialis

  7. Thank you. Loads of content!
    finasterida

  8. Hi! Someone in my Facebook group shared this site with us so I came to take a look. I’m definitely enjoying the information. I’m bookmarking and will be tweeting this to my followers! Superb blog and outstanding style and design.|

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