컨테이너(Container) 란?

- 컨테이너는 어플리케이션을 관련 라이브러리 및 종속항목과 함께 패키지로 묶어 소프트웨어 서비스 구동을 위한 격리 환경을 제공한다.

- 컨테이너는 보통 인스턴스의 생명주기 관리와 추가적인 기능을 제공한다.

  Servlet 컨테이너는 Servlet의 생성, 생성 후 초기화, 서비스 실행, 소멸에 관한 모든 권한을 가지고 있다.

  개발자가 직접 Servlet을 생성하고 서비스하지는 않는다.

- 스프링 컨테이너는 스프링 프레임워크의 핵심부에 위치하며, 종속객체 주입을 이용하여 애플리케이션을 구성하는 컴포넌트들을 관리한다. 

 

IoC(Inversion Of Control, 제어의 역전)란?

- IoC는 객체의 생성, 생명주기의 관리까지 모든 객체에 대한 제어권이 바뀌었다는 것을 의미한다.

즉, 인스턴스 생성에서 소멸까지의 생명주기 관리를 개발자가 아닌 컨테리너가 담당한다는 것을 의미한다.

- 컴포넌트 의존관계 결정(Component Dependency Resolution), 설정(configuration) 및 생명주기(lifecycle)를 해결하기 위한 디자인 패턴(Design Pattern)이다.

- IoC는 객체 간의 결합도를 줄이고 유연한 코드를 작성하게 하여 가독성 및 코드의 중복, 유지보수를 편하게 할 수 있다.

 

IoC 구현 방법

- DL (Dependency Lookup, 의존성 검색)

저장소에 저장되어 있는 Bean에 접근하기 위해 컨테이너가 제공하는 API를 이용하여 Bean을 Lookup

EJB, Spring 등에서 지원

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

각 클래스간의 의존관계를 빈 설정(Bean Definition) 정보를 바탕으로 컨테이너가 자동으로 연결한다.

Constructor Injection, Method(Setter) Injection, Field Injection 등

- Spring, PicoContainer 에서 지원

 

Dependency Injection(의존성 주입)

- 객체 자체가 아니라 Framework에 의해 객체의 의존성이 주입되는 설계 패턴

각 클래스간의 의존관계를 빈 설정(Bean Definition) 정보를 바탕으로 컨테이너가 자동으로 연결

- Framework에 의해 동적으로 주입되므로 모듈 간의 결합도가 낮아지고 유연성이 높아진다.

- Dependency Injection은 Spring Framework에서 지원하는 IoC의 형태

- 의존성 주입 방법

Constructor Injection : 생성자를 이용한 의존성 주입

Method(Setter) Injection : Setter나 일반 메소드를 이용한 의존성 주입

Field Injection : 필드를 통한 의존성 주입

 

 

Dependency Injection(의존성 주입) 장점

- Dependency Reduction : 객체 상호 간 의존성 관계를 줄여준다.

- Reusable Structure : 코드의 재사용과 조합이 용이하다.

- Readability : 코드들이 분리되어 가독성이 높다.

- Loose Coupling & Easy to change : 구조는 변화에 민감하지 않을 수 있다.

- 기타 테스트가 용이하고 다양한 패턴을 적용하는 데 유연하다.

 

<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:util="http://www.springframework.org/schema/util"
	xmlns:task="http://www.springframework.org/schema/task"
	xsi:schemaLocation="
	    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
        http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">
		
	<!-- bean 태그 : 스프링 컨테이너에 빈을 정의(객체 생성) -->
	<!-- 기본 생성자를 이용하여 빈을 정의 -->
	<bean id="userService" class="com.user1.UserServiceImpl"/>
	
	<!-- 생성자로 기본 자료형의 값을 인수로 전달 -->
<!-- 
	<bean id="userService2" class="com.user1.UserServiceImpl2">
		<constructor-arg value="이자바"/>
		<constructor-arg value="010-1111-1111"/> 
		<constructor-arg value="17"/>
	</bean>
-->	
	<bean id="userService2" class="com.user1.UserServiceImpl2">
		<constructor-arg index="0" value="이자바"/>
		<constructor-arg index="2" value="17"/>
		<constructor-arg index="1" value="010-1111-1111"/>
	</bean>

	<!-- 생성자를 이용한 의존성 주입 -->
	<bean id="user" class="com.user1.User">
		<constructor-arg ref="userService2"/>
	</bean>
	
</beans>
<!-- c 네임스페이스를 이용하여 생성자에 값 설정(문자열 또는 기본 자료형) -->
	<bean id="userService2" class="com.user2.UserServiceImpl2"
		c:name="너자바" c:tel="010-2222-2222" c:age="23"/>
	
	<!-- c 네임스페이스를 이용하여 생성자로 의존성 주입 -->
	<!-- init-method : 메소드 설정 - 객체가 생성될 때 단 한 번 호출(초기화 작업이 필요한 경우) -->
	<!-- destroy=method : 메소드 설정 - 객체가 소멸되기 직전 한 번 호출 -->
	<bean id="user" class="com.user2.User"
		c:userService-ref="userService2"
		init-method="init"
		destroy-method="destroy"/>
	<bean id="userService" class="com.user3.UserServiceImpl"/>
	
	<!-- setter를 이용한 프로퍼티 설정(문자열 또는 기본자료형) -->
	<bean id="userService2" class="com.user3.UserServiceImpl2">
		<property name="name" value="다자바"/>
		<property name="tel" value="010-5555-5555"/>
		<property name="age" value="21"/>
	</bean>
	
	<!-- setter를 이용한 의존성 주입 -->
	<!-- 반드시 setter가 존재해야함 -->
	<!-- setter는 name 속성값을 기준으로 첫글자를 대문자로하여 앞에 set을 붙인 메소드명 -->
	<!-- name="userService" => setUserService 라는 메소드명이 존재해야 함 -->
	<bean id="user" class="com.user3.User">
		<property name="userService" ref="userService2"/>
	</bean>
<bean id="userService" class="com.user4.UserServiceImpl"/>
	
	<!-- p 네임스페이스를 이용한 프로퍼티 설정(문자열 또는 기본자료형) -->
	<bean id="userService2" class="com.user4.UserServiceImpl2"
		p:name="홍자바" p:tel="010-1234-5678" p:age="20"/>
	
	<!-- setter를 이용한 의존성 주입 (p 네임스페이스) -->
	<!-- 반드시 setter가 존재해야함 -->
	<bean id="user" class="com.user4.User"
		p:userService-ref="userService2"/>
	<bean id="userService" class="com.user5.UserServiceImpl">
		<property name="name" value="컬렉션"/>
		<property name="address">
			<map>
				<entry key="서블릿" value="서울"/> <!-- <entry key-ref="객체명-1" value-ref="객체명-2"/> -->
				<entry>
					<key><value>스프링</value></key>
					<value>경기</value> <!-- <ref bean="객체명"/> -->
				</entry>
			</map>
		</property>
		<property name="hobby">
			<list>
				<value>게임</value> <!-- <ref bean="객체명"/> -->
				<value>영화</value>
				<value>음악</value>
			</list>
		</property>
		<property name="tels">
			<props>
				<prop key="후후후">010-1111-1111</prop>
				<prop key="호호호">010-2222-2222</prop>
				<prop key="하하하">010-3333-3333</prop>
			</props>
		</property>
	</bean>
	
	<bean id="user" class="com.user5.User">
		<property name="userService" ref="userService"/>
	</bean>
<!-- properties 파일  읽기 -->
	<context:property-placeholder 
		location="classpath:com/user6/user.properties"/>
	
	<bean id="userService" class="com.user6.UserServiceImpl">
		<property name="name" value="${join.name}"/>
		<property name="tel" value="${join.tel}"/>
		<property name="age" value="${join.age}"/>
	</bean>
	
	<bean id="user" class="com.user6.User">
		<property name="userService" ref="userService"/>
	</bean>
<!-- scope : 기본 - singleton : 하나의 객체만 생성 -->
	<bean id="movie" class="com.scope1.Movie"/>
	
	<!-- prototype : 객체를 호출할 때 마다 새로운 객체 생성 -->
	<bean id="music" class="com.scope1.Music" scope="prototype"/>

<bean id="movie" class="com.scope2.Movie" scope="prototype"/>
	<bean id="music" class="com.scope2.Music" scope="prototype">
		<aop:scoped-proxy/> <!-- 메소드를 호출할 때 마다 객체가 생성 -->
	</bean>
	
	<bean id="user" class="com.scope2.User">
		<property name="movie" ref="movie"/>
		<property name="music" ref="music"/>
	</bean>

<!-- scope : 기본 - singleton : 하나의 객체만 생성 -->
<!-- scope="prototype" - 빈을 호출 할 때마다 새로운 객체를 생성 -->	

<!-- 피자 -->
<bean id="pizza" class="com.look.Pizza" scope="prototype"/>

<!-- 베지 피자 -->
<bean id="veggiePizza" class="com.look.Pizza" scope="prototype">
	<property name="isVeg" value="true"/>
</bean>

<!-- 
	룩업 메소드 인젝션 : 컨테이너가 관리하는 빈의 메소드를 재정의하여
					컨테이너 안의 다른 빈을 검색하는 기능 
 -->
<bean id="pizzaShop" class="com.look.PizzaShop">
	<lookup-method name="makePizza" bean="pizza"/>
	<lookup-method name="makeVeggiePizza" bean="veggiePizza"/>
</bean>

 

+ Recent posts