[Spring MVC] 스프링 컨테이너에 대한 요약

600g (Kim Dong Geun)·2020년 8월 18일
3

본 글은 스프링 MVC에 대해 지식을 정리하고 나중에 헷갈릴 때 다시 보기 위한 글입니다 👀

본 게시글은 Spring MVC Quick Start를 참조하여 정리한 글입니다. 📖 👀

본 게시글은 Spring MVC Documentation를 참조하여 정리한 글입니다  📚 👀

스프링 컨테이너란?

스프링 프레임워크는 스프링의 빈을 생성하고 관리하는 컨테이너를 가지고 있다. 이를 통해서 스프링의 주개념인 IOC 나 AOP에 대해서 관리하곤 한다.

그 주체가 바로 오늘 적을 Application Context다.

스프링 컨테이너의 종류

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

Bean Factory

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

일반적으로 스프링 프로젝트에서는 사용될 일이 없지만, ApplicationContext는 BeanFactory를 상속받고 있다는 것을 알아두자.

Application Context

Bean Factory와 마찬가지로, Bean 객체를 생성하고 관리하는 기능을 가지고 있다.
뿐만 아니라 트랜잭션 관리, 메시지 기반의 다국어 처리, AOP 처리등등 DI(Dependency Injection) 과 Ioc(Inverse of Conversion) 외에도 많은 부분을 지원하고 있다.

아무래도 컨테이너가 구동되는 시점에 객체들을 생성하는 Pre-Loading 방식이 Bean Factory와 가장 큰 차이점이 아닌가 싶다. (물론 위에 트랜잭션 관리 이부분도 크지만!)

Applicationn Context의 종류

ApplicationContext는 기본적으로 AbstractApplicationContext의 Interface를 구현한 구현체이다.

기본적인 구현함수로는 getBean("")등이 있겠으나 자세한 내용은 링크를 참조 하길 바란다.

구현 클래스기능
GenericXmlApplicationnContext파일 시스템이나 클래스 경로에 있는 XML 파일을 로딩하여 구동하는 컨테이너다.
XmlWebApplicationContext웹 기반의 스프링 어플리케이션을 개발할 떄 사용하는 컨테이너다.

음 일반적으로 Spring MVC의 환경을 제작하면 대부분 XmlWebApplicationContext가 자동으로 생성되어 사용한다.

Web Application이 아닌 직접 빈을 생성하여 XML 설정 파일을 로딩하여 구동하려면 GenericXmlApplicationContext를 사용한다.

스프링 XML 설정

<beans> Element

스프링 설정 파일 이름은 무엇을 사용하든 상관없지만 <beans>를 루트 엘리먼트로 사용해야 한다. 그리고 <beans> 엘리먼트 시작 태그에 네임스페이스를 비롯한 XML 관련 정보가 설정이 된다.

  • applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://~~~~~~"
              >
</beans>

처럼 Application Context내에서 사용할 기능의 네임스페이스를 관리하는 역할을 한다.

<import> Element

스프링 설정 파일은 앞서 설명했듯이, <bean>을 생성하고 설정하는 것 외에도 다양한 기능(트랜잭션 처리, AOP 관리)을 한다고 했다.

즉 하나의 Application Context에 위 기능을 관리하면 다소 복잡할 수 밖에 없는데, 이를 Import로 해결해주고 있다.

각 기능별로 Application Context.xml을 만들고 import로 불러서 관리를 해주면 유지보수나 나중에 Application Context를 찾아볼때 편하게 찾을 수 있다.

다음과 같이 사용한다.

<beans>
  <import resources="presentation-layers.xml"/>
  <import resources="transactions.xml"/>
</beans>

<bean> Element

스프링 설정 파일에 클래스를 등록하기 위해 사용한다.
즉 이 Bean에 등록되면 스프링 컨테이너가 알아서 이 객체를 관리해준다는 것이다.

어떻게 보면 Spring 설정 파일 중 가장 많이 쓰지 않을 까 싶다. (물론 @Component로)
막간 정리를 해보자면 Annotation에 해도 되지만,,
@Component의 경우 개발자가 직접 컨트롤이 가능한 클래스의 경우 @Component를,
@Bean의 경우 개발자가 직접 컨트롤이 불가능한 클래스의 경우 @Bean으로 올린다 한다.

뭐 아무튼 ApplicationContext에 Bean을 등록하기 위해서는 다음과 같이 등록한다.

  • applicationContext.xml
<beans
       네임스페이스들이 있겠쥬? ㅎㅎ
       >
  <bean class="com.examples.ClassA" id="classA"/>
</beans>

id는 필수 값은 아니지만 (등록을 안하면 자동으로 camelCase 를 따름
클래스 값은 반드시 지정해줘야 한다.

그럼 사용은 어떻게 하냐?

  • Main.java
public class Main{
	public static void main(String[] args){
    	AbstractApplicationContext factory = new GenericXmlApplicationContext("applicationContext.xml");
        
        ClassA classA = factory.getBean("classA");
    }
}

오케이~ 참 쉽쥬? 🤔

Bean 의 속성들

init-method 속성

Servlet 컨테이너는 web.xml파일에 등록된 Servlet 클래스의 객체를 생성할 때 Default 생성자만을 인식한다. 따라서 서블릿은 init() 메소드를 Overriding 하여 멤버 변수를 초기화한다.

스프링 컨테이너 역시 빈즈를 생성할 때 디폴트 생성다를 호출한다.
따라서 객체를 생성한 후에 멤버 변수의 초기화 작업이 필요하다면 Servlet의 Init()과 같은 메소드가 필요하다. 이를 위해서 스프링에서는 bean 엘리먼트의 init-method를 지원한다.

<bean id="classA" class="com.example.ClassA" init-method="initMethod"/>

처럼 init-method를 이용하여 지정할 수 있다.

그렇다면 당연히 ClassA 클래스에 initMethod라는 함수가 구현되어 있어야 할 것이다.

destroy-method 속성

init 메소드는 빈을 생성할떄, 빈이 삭제될 때 메소드는 destory-method를 이용하여 지정한다.
나머지 예제는 위와 같으니 생략하겠다.

lazy-init 속성

앞서 말했듯이, ApplicationContext는 기본적으로 컨테이너 구동시점에 객체들이 생성되는 PreLoading방식을 사용한다고 했다.
그런데 잘 참조되지 않으면서 많은 메모리를 차지하여 시스템에 부담을 주는 객체가 있다면?

그럴 때 객체 생성 시점을 Lazy-Loading화 해 메모리 전략을 하면 된다.

<bean id="classA" class="com.example.ClassA" lazy-init="true"/>

Scope 속성

컨테이너에서 생성한 Bean을 어느범위 까지 지정할 것인가 를 지정하는 것
Default 속성값은 Singleton 구조를 가지고 있다.

속성 값특성
singleton하나의 bean 정의에 대해서 Spring ioc Container내에 단 하나의 객체만 존재한다
prototype하나의 bean 정의에 대해서 다수의 객체가 존재할 수 있다.
request하나의 bean 정의에 대해서 하나의 http request 생명주기 안에 단 하나의 객체만 존재한다. Web-aware spring application context안에서 유효
session하나의 bean 정의에 대해서 하나의 http session의 생명주기에 안에 단 하나의 객체만 존재한다. web-aware spring application context안에서 유효
Global session하나의 Bean 정의에 대해서 하나의 global HTTP Session의 생명주기 안에 단 하나의 객체만 존재한다 Web-aware spring application context안에서 유효

등등이 있다. 내가 알기론 요거 5개까지 있는 것으로 안다.

<bean id="classA" class="com.example.ClassA" scope="prototype"/>

처럼 변경이 가능하다.

profile
수동적인 과신과 행운이 아닌, 능동적인 노력과 치열함

0개의 댓글