컨테이너(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>
'쌍용강북교육센터 > 11월' 카테고리의 다른 글
1117_Spring : Spring Web MVC(Model View Controller) (0) | 2021.11.21 |
---|---|
1117_Spring : 애노테이션을 이용한 객체간 의존 관계 설정 (0) | 2021.11.17 |
1116_Spring : Framework 프레임워크 (0) | 2021.11.17 |
1115_세미프로젝트 : Garment Market (0) | 2021.11.16 |
1110_JSP/Servlet : 커스텀 태그(Custom Tag) - 1 (0) | 2021.11.12 |