- 이 문서는 구루비에서 작성하였습니다.
- 이 문서를 다른 블로그나 홈페이지에 게재하실 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
- 출처 : http://wiki.gurubee.net/pages/viewpage.action?pageId=26740787&
- 구루비 지식창고의 모든 문서는 크리에이티브 커먼즈의 저작자표시-비영리-동일조건변경허락(BY-NC-SA) 라이선스에 따라 자유롭게 사용할 수 있습니다.
IoC(Inversion of Control)의 이해
1. IoC(제어의 역전현상)의 이해
- IoC는 Inversion of Control의 약자이다.
- 우리나라 말로 직역해 보면 "역제어"라고 할 수 있다. 즉 제어의 주체가 바뀌었다. 누구로? Ioc 컨테이너로
1.1 제어의 역전현상 이란?
- 기존에 자바 기반으로 어플리케이션을 개발할 때 자바 객체를 생성하고 서로간의 의존 관계를 연결시키는 작업에 대한 제어권은 보통 개발되는 어플리케이션에 있었다.
- 그러나 Servlet, EJB 등을 사용하는 경우 Servlet Container, EJB Container에게 제어권이 넘어가서 객체의 생명주기(Life Cycle)를 Container들이 전담하게 된다.
- 이처럼 IoC에서 이야기하는 제어권의 역전이란 객체의 생성에서부터 생명주기의 관리까지 모든 객체에 대한 제어권이 바뀌었다는 것을 의미한다.
1.2 IoC의 장/단점
장점
- 인터페이스 기반 설계가 가능.
- 컴퍼넌트 재사용성 증가
- 체계적이고 효율적인 Dependency 관리
단점
- 제어구조가 반대로 되어 있으므로 이해하기 어려운 코드가 될 수 있음
1.3 컨테이너(Container)란?
Servlet Container
- Servlet의 생성, 생성 후 초기화, 서비스 실행, 소멸에 관한 모든 권한을 가지면서 Servlet의 생명주기를 관리한다.
- 개발자들이 직접 Servlet을 생성하고 서비스하지는 않는다.
- 멀티 스레딩을 지원하여 클라이언트의 다중 요청을 알아서 처리해준다.
- 대표적인 Conatainer에는 Tomcat, jetty, jboss 등이 있다
EJB Container
- EJB(세션빈, 엔티티빈)의 생성, 생성 후 초기화, 서비스 실행, 소멸에 관한 모든 권한을 가지면서 EJB의 생명주기를 관리한다.
- Transaction, Security, EJB Pooling등의 추가적인 기능을 제공하고 있다.
IoC Container
- IoC를 구현하는 프레임워크로 객체를 관리하고, 객체의 생성을 책임지고, 의존성을 관리하는 컨테이너 이다.
- 즉 POJO 생성, 초기화, 서비스 소멸에 관한 모든 권한을 가지면서 POJO의 생명주기를 관리한다.
- 개발자들이 직접 POJO를 생성할 수도 있지만, 모든 권한을 Container에게 맡긴다.
1.4 Ioc 분류체계
![]() |
2. DI(Dependency Injection) 및 DL(Dependency Lookup)의 이해
2.1 Dependency Injection(의존성 삽입)의 이해
- Dependency Injection이란 각 클래스 사이의 의존관계를 빈 설정(Bean Definition)정보를 바탕으로 컨테이너가 자동적으로 연결해주는 것을 말한다.
- 개발자들은 단지 빈 설정파일(저장소 관리 파일)에서 의존관계가 필요하다는 정보를 추가하기만 하면 된다.
Dependency Injection의 장점
- 코드가 단순해 진다.
- 컴포넌트간의 결합도가 제거된다.
- 테스트가 유리하다. Mock/Stub 사용 가능
Dependency Injection의 분류
- Constructor Injection : 컴퍼넌트의 dependency 가 constructor의 argument를 통해 제공되는 방식
- Setter Injection : 컴퍼넌트의 dependency 가 JavaBean-style setter를 통해 제공되는 방식
- Method(Interface) Injection : 컴퍼넌트의 dependency 가 일반 메소드를 통해서 제공되는 방식 (거의 사용하지 않으므로 배우지 않겠다.)
- Setter를 통해 의존성이 있는 객체를 삽입하는 방법
Setter Dependency Injectionl
<!-- JAVA --> public class ObjectListBO { private ObjectListDAO objectListDAO; // Setter Dependency Injection public void setObjectListDAO(ObjectListDAO objectListDAO) { this.objectListDAO = objectListDAO; } public List<Emp> getEmployeeList() { return objectListDAO.selectEmployeeList(); } } <!-- 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://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd default-autowire="byName"> <bean id="objectListBO" class="com.spring.ioc.bo.ObjectListBO" > <property name="objectListDAO" ref="objectListDAO" /> </bean> <bean id="objectListDAO" class="com.spring.ioc.dao.ObjectListDAO" /> </beans>
- Constructor를 통해 의존성이 있는 객체를 삽입하는 방법
Setter Dependency Injectionl
<!-- JAVA --> public class ObjectListBO { private ObjectListDAO objectListDAO; // constructor Dependency Injection public ObjectListBO(ObjectListDAO objectListDAO) { this.objectListDAO = objectListDAO; } public List<Emp> getEmployeeList() { return objectListDAO.selectEmployeeList(); } } <!-- 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://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd default-autowire="byName"> <bean id="objectListBO" class="com.spring.ioc.bo.ObjectListBO" > <constructor-arg ref="objectListDAO" /> </bean> <bean id="objectListDAO" class="com.spring.ioc.dao.ObjectListDAO" /> </beans>
2.2 DI XML <bean> 태그
<property>
- Setter Dependency Injection 에서 사용
- name속성은 setter 메소드 명
- ref 속성은 의존성 주입할 객체 명
- value는 Bean이 아닌 Object를 의존성 주입 할 때 사용
<constructor-arg>
- Constructor Dependency Injection에서 사용
- ref 속성은 의존성 주입할 객체 명
- value는 Bean이 아닌 Object를 의존성 주입 할 때 사용
- type 속성은 파라미터 타입을 명시 (type=java.lang.String)
2.3 DL의 이해
- 컨테이너 API 를 이용해 저장소에 의해 관리되고 있는 bean을 개발자들이 직접 Lookup 하여 사용한다.
- Dependency Pull 이라고도 불리운다.
- 자바 개발자들에게 친숙한 전통적인 접근법 이다.
- Dependency Lookp 예제
Dependency Lookup
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring/applicationContext-ioc.xml"); ObjectListDAO objectListDAO = (ObjectListDAO) ctx.getBean("objectListDAO");
3. Bean Scope
3.1 Bean Scope란
- Bean Scope는 객체가 유효한 범위로 아래 5가지의 scope가 있다.
Scope 설명 singleton 하나의 Bean 정의에 대해서 Spring IoC Container 내에 단 하나의 객체만 존재한다. prototype 하나의 Bean 정의에 대해서 빈을 사용할 때 마다 객체를 생성 한다. request HTTP 요청마다 객체를 생성 한다. 즉 HTTP request의 생명주기 안에 단 하나의 객체만 존재한다 session HTTP 세션마다 객체를 생성 한다. 즉 HTTP Session의 생명주기 안에 단 하나의 객체만 존재한다 global-session 글로벌 HTTP 세션 안에 단 하나의 객체만 존재한다
3.2 Singleton Scope
- Bean이 singleton인 경우, 단지 하나의 공유 객체만 관리된다.
- Singleton scope은 Spring의 기본(default) scope이다.
- Container 당 하나의 객체라는 의미에서 singleton 이다. JVM의 classloader당 하나의 객체라는 의미의 GoF의 Singleton과는 다르다
Singleton Scope 예
<bean id="articleBO" class="com.oracleclub.ArticleBOImpl"/> <bean id="articleBO" class="com.oracleclub.ArticleBOImpl" scope="singleton"/> <bean id="articleBO" class="com.oracleclub.ArticleBOImpl" singleton="true"/>
3.3 Prototype Scope
- prototype scope로 정의된 bean은 필요한 매 순간 새로운 bean 객체가 생성된다.
- bean을 요청 할 때 DI 되거나 getBean(String)에 의해 호출 될 때 마다 새로운 객체를 만들어 준다.
Prototype Scope 예
<bean id="articleBO" class="com.oracleclub.ArticleBOImpl" scope=" prototype"/> <bean id="articleBO" class="com.oracleclub.ArticleBOImpl" singleton="false"/>
3.4 기타 Scope
- request, session, global session scope을 사용하기 위해서는 추가적인 설정이 필요하다.
- Servlet 2.4+ web container를 사용하고, JSF나 Struts 등과 같이 Spring의 DispatcherServlet의 외부에서 요청을 처리하는 경우, 다음 javax.servlet.ServletRequestListener를 'web.xml' 파일에 추가해야 한다.
- struts를 사용하는 경우 web.xml의 예
web.xml 예
<listener> <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> </listener>
Request Scope
- 아래는 Request Scope의 설정 예이다.
Request Scope 예
<bean id="articleWriteAction" class="com.oracleclub.article.action.ArticleWriteAction" scope="request"/>
Session Scope
- 아래는 Session Scope의 설정 예이다.
Session Scope 예
<bean id="userInfo" class="com.oracleclub.user.UserSessionInfo" scope="session"/>
Global Session Scope
- 아래는 Global Session Scope의 설정 예이다.
Global Session Scope 예
<bean id="userInfo" class="com.oracleclub.user.UserSessionInfo" scope="globalSession"/>
4. BeanFactory와 ApplicationContext
4.1 BeanFactory
- BeanFactory 인터페이스는 Spring IoC Container의 기능을 정의하고 있는 기본 인터페이스이다.
- Bean의 생성 및 종속성 주입, 생명주기 관리등의 기능을 제공한다.
BeanFactory 예
BeanFactory factory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml")); HelloService service = (HelloService) factory.getBean("helloService");
4.2 ApplicationContext
- BeanFactory 인터페이스를 상속받는 ApplicationContext는 BeanFactory가 제공하는 기능외에 Spring AOP, 메시지 리소스처리(국제화에사용됨), 이벤트 처리등의 기능을 제공한다.
- 모든 ApplicationContext 구현체는 BeanFactory의 기능을 모두 제공하므로, 특별한 경우를 제외하고는 ApplicationContext를 사용하는 것이 바람직하다.
- Spring Framework는 다수의 ApplicationContext 구현체를 제공한다.
- applicationContext를 구현한 클래스들
- AbstractApplicationContext
- AbstractRefreshableApplicationContext
- AbstractRefreshablePortletApplicationContext
- AbstractRefreshableWebApplicationContext
- AbstractXmlApplicationContext
- ClassPathXmlApplicationContext
- FileSystemXmlApplicationContext
- GenericApplicationContext
- GenericWebApplicationContext
- StaticApplicationContext
- StaticPortletApplicationContext
- StaticWebApplicationContext
- XmlPortletApplicationContext
- XmlWebApplicationContext
문서정보
- 이 문서는 구루비에서 작성하였습니다.
- 이 문서를 다른 블로그나 홈페이지에 게재하실 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
- 출처 : http://wiki.gurubee.net/pages/viewpage.action?pageId=26740787&
- 구루비 지식창고의 모든 문서는 크리에이티브 커먼즈의 저작자표시-비영리-동일조건변경허락(BY-NC-SA) 라이선스에 따라 자유롭게 사용할 수 있습니다.