Study Note

Spring IoC 컨테이너 본문

Spring

Spring IoC 컨테이너

moreLearn 2020. 2. 19. 04:20

IoC란

IoC는 Inversion of Control의 약자로 제어의 역행이라고 하며 결합도와 관련된 개념입니다,

자바 기반으로 application을 개발할 때 객채의 생성, 제어, 의존관계 등 개발자가 직접 코드로 처리해야 합니다.

제어의 역행은 위와 같은 작업을 컨테이너로 처리함으로써 객체 생성, 의존관계에 대한 소스코드가 사라져 낮은 결합도를 이룰 수 있습니다.

 

컨테이너의 예로 servlet 컨테이너가 있습니다.

간단하게 다음과 같은 순서로 진행됩니다.

  1. web.xml 파일을 로딩하여 컨테이너가 구동된다.
  2. client로 부터 /index 요청을 받는다.
  3. url과 맡는 객체를 찾아 home() 메소드를 호출한다.
  4. home()의 결과를 client로 전송한다.

home() 메소드에서 return을 "index"로 하면 index.html을 전송하도록 spring을 설정했기 때문에 return이 "index"입니다.

 

spring 컨테이너 종류

spring에는 BeanFactory와 BeanFactory를 상속한 ApplicationContext가 있습니다.

 

BeanFactory는 스프링 설정 파일에 등록된 <bean> 객체를 생성하고 관리하는 기본적인 컨테이너입니다.

또한 BeanFactory는 클라이언트의 요청(Lookup)에 의해서만 <bean> 객체가 생성되기 때문에 지연로딩(Lazy Loading)이 발생한다. 이런 이유로 보통 BeanFactory를 사용할 일이 없습니다.

 

ApplicationContext는 BeanFactory를 상속받았기 때문에 BeanFactory의 <bean> 객체 관리 가능을 가지고 있으면서 트랜잭션 관리, 메시지 기반의 다국어 처리 등 다양한 기능을 제공합니다.

또한 ApplicationContext는 컨테이너가 구동되는 시점에 <bean> 객체를 생성하는 방식인 즉시로딩(Pre Loading)으로 동작합니다.

spring XML 설정

spring은 xml을 통해 <bean>의 생명주기를 관리하고 여러 서비스를 제공한다. 다음과 같은 element를 통해 xml 설정 파일을 만듭니다.

 

  • <beans> root element
  • <import> element
  • <bean> element
  • <description> element
  • <alias> element

<beans>는 spring 설정 파일의 root element이며, <beans>의 시작 태그에 namespace와 XML 스키마 관련 정보가 설정됩니다. xsi:schemaLocation에 등록된 spring-beans.xsd 때문에 위의 <beans> 외의 다른 element를 사용할 수 있다. 주로 <import>와 <bean>을 많이 사용합니다.

<?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://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">

<beans>

 

<import>는 다른 xml 파일을 하나로 통합할 때 사용합니다. spring 설정 파일에 다양한 <bean>을 등록해서 사용할 수 있습니다. 하지만 다양한 기능을 가지고 있는 <bean>들을 하나의 설정 파일에서 관리하는건 무척 힘듭니다. 이런 이유로 <bean> 설정 파일을 나누고 <import>를 통해 하나로 통합해서 사용할 수 있습니다.

 

<bean>을 사용하여 spring 설정 파일에 클래스를 등록하며 다음과 같은 속성을 가지고 잇습니다.

  • id : <bean> 객체의 이름을 지정할 때 사용하며 생략이 가능하다. 보통 이름은 CamelCase를 사용한다.
    (공백, 숫자, 특수기호를 사용하면 error가 발생한다.)
  • class : 등록할 클래스의 정확한 패키지 경로과 클래스 이름을 지정하는 곳이며 생략할 수 없다.
  • init-method : 객체 생성시 초기화 작업이 필요할 경우 init-method에 메소드를 지정하여 초기화 할 수 있다.
  • destroy-method : spring 컨테이너가 객체를 삭제하기 직전에 호출할 메소드를 지정할 수 있다.
  • lazy-init : lazy-init="true"로 설정하면 <bean> 객체를 BeanFactory의 지연로딩(Lazy Loading)으로 동작한다.
  • scope : scope는 defult 값이 singleton이다. 해당 객체에 defult로 GoF 디자인 패턴의 싱글톤 객체로 생성되어 1개의 객체만 사용된다. 만약 요청될 때마다 새로운 객체를 생성하여 반환하고 싶을땐 prototype으로 설정하면 된다.

IoC 의존성 주입

IoC는 2가지 형태가 있습니다.

  • Dependency Lookup : 저장소에서 관리되고 있는 bean을 api를 이용하여 lookup하는 방법
  • Dependency Injection :  의존관계를 bean 설정 정보를 통해서 container가 자동적으로 연결해 주는것

보통 Dependency Lookup 보다는 Dependency Injection을 많이 사용합니다.

 

Dependency Lookup은 다음과 같이 사용할 수 있습니다.

<bean id="user" class="exampleUser"/>
	public static void main(String[] args) {
		AbstractApplicationContext factory = new GenericXmlApplicationContext("applicationContext.xml");
		User user = (User) factory.getBean("user");
		factory.close();
	}

 

Dependency Injection에는 3가지 방법이 있습니다.

  • Setter Injection
  • Constructor Injection
  • Method Injection

Setter Injection은 setter를 사용한 방식입니다.

	<bean id="user" class="polymorphism.User" >
		<property name="name" value="ish"></property>
		<property name="age" value="24"></property>
	</bean>	
public class User {
	String name;
	int age;
	
	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}
}

Constructor Injection은 생성자를 이용한 방식입니다.

	<bean id="user" class="example.User" >
		<constructor-arg value="ish"></constructor-arg>
		<constructor-arg value="24"></constructor-arg>
	</bean>		
	public User(String name, int age) {
		this.name = name;
		this.age = age;
	}

 

 

 

 

 

'Spring' 카테고리의 다른 글

Spring Model  (0) 2020.02.18
Spring 프레임워크  (0) 2020.02.18