Spring Container

ssongkim·2022년 1월 9일
0
post-thumbnail

Spring (IoC) Container

스프링 컨테이너는 스프링 프레임워크의 핵심이며 스프링 빈의 생명 주기를 관리하여 Spring 프레임워크의 특징인 IoC(제어역전)DI(의존성주입)을 제공해주는 역할을 한다.

스프링 컨테이너는 Bean Factory와 이를 상속한 ApplicationContext 2가지 유형이 존재한다.

Bean Factory

Bean Factory는 스프링 컨테이너 설정파일에 등록된 Bean 객체를 생성하고 관리하는 기본적인 기능만 담당하는 IoC 컨테이너이자 클래스를 말한다.
컨테이너가 구동될 때 Bean 객체를 생성하는 것이 아니라 빈 사용 요청에 의해서 Bean 객체가 사용되는 시점(Lazy Loading) 에 객체를 생성하는 방식이다.

ApplicationContext

ApplicationContext는 BeanFactory 인터페이스의 하위 인터페이스이다.
Spring에서는 빈의 생성과 관계설정 같은 제어를 담당하는 IoC(Inversion of Control) 컨테이너인 빈 팩토리(Bean Factory)가 존재한다. 하지만 실제로는 빈의 생성과 관계설정 외에 추가적인 기능이 필요한데 트랜잭션 관리, 메시지 기반의 다국어 처리, AOP 처리 등 DI(Dependency Injection) 과 Ioc(Inverse of Conversion) 외에도 많은 부분을 지원하는 ApplicationContext를 사용한다.
컨테이너가 구동되는 시점에 Bean 객체들을 생성하는 Pre-Loading 방식이다.

ApplicationContext는 기본적으로 AbstractApplicationContext의 Interface를 구현한 구현체로 여러 종류의 구현체가 존재한다.

ApplicationConext 구현체 종류

  1. GenericXmlApplicationContext: XML설정파일을 로딩하여 구동하는 컨테이너
  2. WebApplicationContext
    • XmlWebApplicationContext: xml 설정 파일을 불러와 웹 기반의 스프링 애플리케이션을 개발할 때 사용하는 컨테이너
    • AnnotationConfigWebApplicationContext: 자바 설정 파일 형태로 불러와 웹 기반의 스프링 애플리케이션을 개발할 때 사용하는 컨테이너

WebApplicationContext란 Spring의 ApplicationContext를 확장한 인터페이스로, 웹 애플리케이션에서 필요한 몇 가지 기능을 추가한 인터페이스다. 예를 들면 WebApplicationContext의 구현체는 getServletContext라는 메소드를 통해 ServletContext를 얻을 수 있다.


XML 설정 파일과 자바 설정 파일

스프링 컨테이너를 생성할 때 사용하는 스프링 빈에 대한 정의가 되어있는 스프링 컨테이너 설정파일

XML 파일 형태로 설정을 구성할 수도 있고 자바 클래스 형태로 설정을 구성할 수도 있다. 빈을 정의해서 설정파일을 구성하면 이는 스프링 컨테이너를 생성하는데 사용된다.
빈을 정의하는 방법에 대해서는 [이전게시글 Spring Bean]을 확인하자

Component Scan

@Component 어노테이션이 붙은, 빈으로 등록 될 준비를 마친 클래스들을 스캔하여, 빈으로 등록해준다.

XML 설정 파일에서는 <component-scan/> 자바 설정 파일에서는 @ComponentScan을 이용해 스캔 범위를 지정하여 사용한다. 스캔하지 않을 필터지정도 가능하다.

@Configuration, @Controller, @Service, @Component, @Repository 어노테이션은 내부적으로 @Component 어노테이션을 포함하고 있다. 이들을 인식해 스캔하여 컨테이너에서 관리하는 Bean으로 등록한다.

이때 스프링 빈의 기본 이름은 클래스명을 사용하되 맨 앞글자만 소문자를 사용한다.

@Configuration

@Configuration는 해당 클래스가 자바 설정 파일임을 Spring에 알려주는 어노테이션이다.

@Bean

@Bean 어노테이션은 @Bean 어노테이션이 붙은 메소드가 Application Context에 Bean으로 등록되어야 하는 객체를 리턴할 것임을 Spring에 알려준다. @Configuraiton 안에 사용되야하며 @Configuration을 사용하지 않으면 컨테이너에서 빈으로 등록은 되나 싱글톤이 유지되지 않는다.

이때 스프링 빈의 기본 이름은 메서드 명을 사용한다.

스프링 빈 이름 충돌

스프링 빈 등록 시 이름이 충돌될 경우 Exception을 발생시킽다.

띠요옹..

@Configuration을 이용해 자바 설정 파일을 사용하려면 AnnotationConfigWebApplicationContext만 사용해야할 것 같지만 @Configuration어노테이션 스프링 공식 문서를 확인해보니 XML설정 파일에서 @Configuration지정한 클래스를 직접 빈으로 등록해 사용하여 XmlWebApplicationContext 내에서도 쓸 수 있는 것 같더라.., @BeanXmlWebApplicationContext로 등록이 될거같지만 정말 되는지는 나중에 확인해보고 싶다.

spring MVC 활성화

스프링 MVC에서 필요로 하는 컴포넌트, 빈들을 개발자가 일일이 빈 정의 해주는 것은 매우 귀차니즘한 노가다문제가 되며 정의하는 과정에서 실수가 발생할 수 있다. 스프링은 역시 이를 자동화해준다. (따봉)

예를 들어 DispatcherServlet은 스프링 컨테이너로부터 HandlerMapping, HandlerAdapter, ViewResolver 구현체 전략 빈을 받아 사용한다. 이러한 작업은 개발자가 직접 하나하나 명시하지는 않고 사용 선언만 해주어도 대부분 디폴트 선언으로 자동화 해준다.

XML 설정 파일에서는 <annotation-driven/> 자바 설정 파일에서는 @EnableWebMvc를 선언하여 활성화한다.

활성화를 안해주면 @Controller 선언된 클래스는 그냥 일반 빈으로 등록될 뿐이다. 활성화를 해줌으로써 @RequestMapping, @ExceptionHandler 등과 같은 어노테이션을 통해 해당 기능을 사용할 수 있도록 한다.

@EnableWebMvc

XML 설정 파일의 <annotation-driven/>와 자바 설정 파일의 @EnableWebMvc는 완전히 동일하지는 않고 유사하다. <annotation-driven/>은 사실 자바 설정 파일로 치면 @AnnotationDrivenConfig와 동일하다.
<annotation-driven/>을 선언하면 DispatcherServlet에서 컨트롤러로 dispatch하기 위한 HandlerMapping, HandlerAdapter 전략 빈을 설정 파일에 알아서 정의해준다.

하지만 자바 설정 파일로 spring MVC를 활성화할 땐 @EnableWebMvc를 사용한다. @EnableWebMvc<annotation-driven/>을 포함하는 여러 config를 자동설정 해주는 좀 더 포괄적인 기능을 수행하는듯 하다.
@EnableWebMvc 주석은 애플리케이션에서 Spring MVC를 활성화하는 데 사용되며 WebMvcConfigurationSupport에서 Spring MVC 구성을 가져와 작동한다. @EnableWebMvc만 켜도 대부분 디폴트 설정을 해주지만 일부 설정을 개발자가 커스터마이즈할 수 있다.

@Configuration
@EnableWebMvc
@ComponentScan("com.studyspring.basic")
public class ServletConfiguration implements WebMvcConfigurer{
	@Override
	public void configureViewResolvers(ViewResolverRegistry registry) {
		// TODO Auto-generated method stub
		InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
		viewResolver.setPrefix("/WEB-INF/views/");
		viewResolver.setSuffix(".jsp");
		registry.viewResolver(viewResolver);
	}

	@Override
	public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
		// TODO Auto-generated method stub
		configurer.enable();
	}

	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		// TODO Auto-generated method stub
		registry.addResourceHandler("/resources/**").addResourceLocations("/resources/").setCachePeriod(31556926);
	}
    
    
}

@Configuration, @EnableWebMvc를 선언하고 WebMvcConfigurer 구현체를 만들면 된다.
재정의를 해줌으로써 커스터마이징 할 수 있다. ViewResolver와 리소스 핸들러를 커스터마이즈한 모습을 확인할 수 있다.

마무리

오늘은 저번 시간의 스프링 빈에 이어 스프링 컨테이너에 대해 알아보았다. 다음에는 DispatcherServlet과 스프링 컨테이너의 생성 과정에 대해 알아보려고 한다.

참고자료

https://gunju-ko.github.io/toby-spring/2019/03/25/IoC-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%EC%99%80-DI.html

https://velog.io/@ehdrms2034/Spring-MVC-Application-Context.xml#bean-%EC%9D%98-%EC%86%8D%EC%84%B1%EB%93%A4

profile
鈍筆勝聰✍️

0개의 댓글