Spring - 애플리케이션 컨텍스트 구성하기

 

XML 파일, Annotarion, JAVA를 이용한 ApplicationContext 구성하기

Spring의 의존성 주입 (Dependency Injection, DI) - 1

  • Spring의 의존성 주입 컨테이너의 핵심은 BeanFactory 인터페이스 이다.
  • BeanFactory는 컴포넌트의 라이프사이클과 의존성을 관리한다.
  • Spring은 XML 파일 또는 Properties 파일을 이용하여 bean 구성을 관리할 수 있다.
  • 아주 작은 애플리케이션이 아니라면 XML로 관리하는 것이 유리하다.
  • ApplicationContext는 BeanFactory를 상속한 인터페이스로 DI 서비스, 트랜잭션 서비스, AOP 서비스, 국제화를 위한 메시지 소스, 애플리케이션 이벤트 처리 등의 서비스를 제공한다.
  • 웹 컨테이너 환경에서는 ContextLoaderListner를 이용하여 구동한다(web.xml에 구성).

애플리케이션 컨텍스트 구성하기

  • ApplicationContext를 구성하는 방법은 XML 파일을 이용하는 방법 애노테이션을 이용하는 방법 자바 로 구성하는 방법 등이 있다.
  • XML 구성으로 경우 ApplicationContext 구성을 위한 context, AOP 구성을 위한 aop, 트랜잭션 지원을 위한 tx 등의 네임스페이스를 제공한다.
  • <context:component-scan> 태그는 bas-package에 지정한 패키지의 하위에 있는 모든 클래스 내에 @Autowired, @Inject, @Resource, @Component, @Controller, @Repository, @Service 등이 애노테이션이 선언되어 의존선 주입이 가능한 빈의 코드를 스캔하도록 스프링에 지시한다.
<?xml version=“1.0” encoding=“UTF-8”>
<beans ...>

<context:component-scan base-package=“스캔할_패키지" />

</beans>
  • 또한 base-package에 지정한 패키지 하위에 있으나 스캔에서 제외할 클래스나 인터페이스를 별도로 지정할 수 있다.
<?xml version=“1.0” encoding=“UTF-8”>
<beans >

<context:component-scan base-package=“스캔할_패키지”>
	<context:exclude=filter type="assignable" expression="제외할 클래스 경로" />
	<!-- type의 값으로는 annotation, regex, assignable, AspectJ, custom 등이 올 수 있다. -->
</context:component-scan>

</beans>
  • XML로 구성하기 : 의존성 주입을 위한 bean 구성. p 속성을 이용하여 주입될 의존성을 지정해준다.
<?xml version=“1.0” encoding=“UTF-8”>
<beans >

<bean id="renderer
		class="com.apress...StandardOutMessageRenderer"
		p:messageProvider-reg="provider" />

<bean id="provider"
		class="com.apress...HelloWorldMessageProvider" />
</beans>
  • Annotation으로 구성하기 : bean 클래스에 적절한 스테레오 타입 애노테이션이 적용되어야 하며 의존성 주입에 사용될 메서드나 생성자에 @Autowired를 적용한다.

스테레오 타입 애노테이션 : 빈을 정의하는 데 사용되는 모든 애노테이션. Org.springframework.stereotype 패키지의 일부이다.

...
@Component(provider)
public class HelloWorldMessageProvider implements MessageProvider {

    ...
}
...
@Service(renderer)
public class StandardOutMessageRenderer implements MessageRenderer {

	private MessageProvider messageProvider;

	

	@Override
	@Autowired
	public void setMessageProvider(MessageProvider provider) {
		this.messageProvider = provider;
	}

	...
}
<?xml version=“1.0” encoding=“UTF-8”>
<beans >

<context:component-scan base-package=“스캔할_패키지" />

</beans>
  • 두 방법 중 어느 방법이더라도 ApplicationContext에서 bean을 얻는 방법은 동일하다.
...
public static void main(String args) {
	GenericXmlApplicationContext cox = new GenericXmlApplicationContext();
	ctx.load(classpath:spring/app-context-xml.xml);
	ctx.refresh();

	MessageRenderer messageRenderer = ctx.getBean(renderer, MessageRenderer.class);;
	messageRenderer.render();
	ctx.close();
}
...
  • 자바로 구성하기 : @Configuration 애노테이션을 적용한 클래스 내에 @Bean 애노테이션이 적용된 메서드를 구현하여 구성한다.
...
@Configuration
public class HelloWorldConfiguration {

	@Bean
	public MessageProvider provider() {
		return new HelloWorldMessageProvider();
	}

	@Bean
	public MessageRenderer renderer() {
		MessageRenderer renderer = new StandardMessageRenderer();
		renderer.setMessageProvider(provider());
		return renderer;
	}
}
  • 자바 구성의 경우 ApplicationContext 구현체를 바꾸어야 한다.
...
public static void main(String args) {
	ApplicationContext cox = new AnnotationConfigApplicationContext(HelloWorldConfiguration.class);

	MessageRenderer mr = ctx.getBean(renderer, MessageRenderer.class);
	mr.render();
}
...
  • 자바 구성 클래스에 @ComponentScan 애노테이션을 사용하면 @Bean 애노테이션이 적용된 메서드를 생략해도 된다.
...
@ComponentScan(basePackages = {"스캔할_패키지"})
@Configuration
public class HelloWorldConfiguration {
}
  • 자바 구성에서 @ImportResource 애노테이션을 이용하여 기존의 xml 구성을 가져와 사용할 수도 있다.
...
@ImportResource(location = {"classpath:spring/app-context-xml.xml"})
@Configuration
public class HelloWorldConfiguration {
}