티스토리 툴바

Model&View helper pattern


'Programming > JSP' 카테고리의 다른 글

Model&View helper pattern  (0) 2010/12/10
Dependency Injection과 스프링 프레임워크  (0) 2010/12/03
JSP구성요소  (0) 2010/12/03
동적쿼리  (0) 2010/12/02
페이지 알고리즘  (0) 2010/12/02
달력  (0) 2010/12/02

Dependency Injection과 스프링 프레임워크

  □ DI (Dependency Injection)
    ■ 정의
      - 스프링 컨테이너가 지원하는 핵심 개념 중 하나.
      - 객체 사이의 의존 관계를 객체 자신이 아닌 외부의 조립기가 수행.
    ■ 예제
      ○ WriteArticleServiceImpl과 ArticleDao의 관계
        - WriteActicleServiceImpl 클래스는 ArticleDao 인터페이스에 의존.
          (실제로는 ArticleDao 인터페이스를 구현한 MysqlArticleDao 클래스의 객체나 OracleArticleDao 클래스의 객체에 의존.)
      ○ 실제 생성된 객체 간의 의존 관계
        - WriteActicleServiceImpl 클래스는 실제로 의존할 객체를 지정할 수 있는 방법을 필요로 함.
      ○ 실제로 의존하는 객체를 지정하는 방법
        ● 코드에 직접 명시
          - WriteArticleServiceImpl 클래스 코드에 직접 MysqlArticleDao 객체에 의존한다고 명시.
 public class WriteArticleServiceImpl {
    // 코드에 직접 의존 객체 명시.
    private ArticleDao articleDao = new MysqlArticleDao();
 }
          □ 단점
            - 단위 테스트를 어렵게 만듬.
              (올바르게 동작하는 MysqlArticleDao 클래스가 반드시 존재해야 함. articleDao 멤버 필드에 mock 객체를 할당할 수 없음.)
            - 의존하는 클래스가 변경되는 경우 코드를 변경해야 함.
              (의존하는 클래스가 MysqlArticleDao에서 OracleArticleDao로 변경해야하는 경우 코드를 변경한 뒤 재컴파일 해야함.)
        ● Factory 패턴이나 JNDI 등을 사용해서 의존 클래스를 검색
 public class WriteArticleServiceImpl {
    private ArticleDao articleDao = ArticleDaoFactory.create();
 }

          -  ArticleDaoFactory 클래스는 ArticleDao 인터페이스를 구현한 클래스 중 에서 어떤 클래스를 사용해야 할지의 여부를 알기 위해

             외부의 설정파일을 사용할 수 도 있고, 시스템 프로퍼티를 사용할 수 도 있음.
          □ 단점
            - 단위 테스트를 하려면 올바르게 동작하는 Factory 또는 JNDI에 등록된 객체를 필요로 함.
        ● 외부의 조립기를 사용
          - 의존 관계에 있는 객체가 아닌 외부의 조립기가 각 객체 사이의 의존 관계를 설정.
          - 조립기가 의존 관계를 관리해 주는 방식을 Dependency Injection (DI) 패턴이 라고 함.
          □ DI 패턴에서는 조립기(assembler)가 객체 간의 의존 관계를 관리

            - WriteArticleServiceImpl 클래스의 코드는 MysqlArticleDao 객체를 생성하거나 검색하기 위한 코드가 포함되어 있지 않음.
            - 조립기의 역할을 하는 Assembler가 MysqlArticleDao 객체를 생성한 뒤 WriteArticleServiceImpl 객체에 전달.
          □ WriteArticleServiceImpl class
 public class WriteArticleServiceImpl {
    private ArticleDao articleDao;

    // 생성자에서 의존하는 객체를 전달 받음.
    public WriteArticleServiceImpl(ArticleDao articleDao) {
        this.articleDao = articleDao;
    }
 }
           - 의존 객체를 직접 생성하지도 않고, Factory나 JNDI를 이용하지도 않음.
              (WriteArticleServiceImpl 클래스는 단지 의존 객체를 전달 받을 수 있는 메서드나 생성자만을 제공.)
          □ Assembler class
            - WriteArticleServiceImpl 객체에 의존 객체를 전달.
 public class Assembler {
    public WriteArticleService getWriteArticleService() {
        ArticleDao articleDao = new MysqlArticleDao();
        WriteArticleService service = WriteArticleServiceImpl(articleDao);

        return service;
    }
 }
          □ UsingService class
 public class UsingService {
    public void useService() {
        // 조립기로부터 사용할 객체를 구함.
        WriteArticleService service = assembler.getWriteArticleService();
       
        service.write(...);
        ......
    }
 }
            - 조립기로부터 WriteArticleServiceImpl 객체를 구해서 사용.
          □ DI 패턴 적용 시 장점
            - 불필요한 의존 관계를 없애거나 줄일 수 있다.
            - 인터페이스에만 의존.
            - 단위 테스트를 수행하는게 수월해짐. (mock 객체와 같은 가짜 객체를 이용하여 클래스를 테스트할 수 있음.)
    
  □ 스프링에서의 DI
    ■ 예제
      ○ DI 패턴에서는 조립기(assembler)가 객체 간의 의존 관계를 관리
      ○ DI 패턴을 적용한 자바 코드
        - WriteArticleServiceImpl 클래스는 생성자나 설정 메서드를 이용하여 의존 객체를 전달 받을 수 있음.
        ● WriteArticleServiceImpl 클래스
 /* 생성자 방식 이용. */
 package kame.sping.chap01;

 public class WriteArticleServiceImpl implements WriteArticleService {
    private ArticleDao articleDao;

    public WriteArticleServiceImpl(ArticleDao articleDao) {
        this.articleDao = articleDao;
    }

    @Override
    public void write(Article article) {
        System.out.println("WriteArticleServiceImpl.write() 메서드 실행");
        articleDao.insert(article);
    }
 }
 /* 설정 메서드 방식 이용. */
 package kame.sping.chap01;

 public class WriteArticleServiceImpl implements WriteArticleService {
    ...
    public void setArticleDao(ArticleDao articleDao) {
        this.articleDao = articleDao;
    }

    @Override
    public void write(Article article) {
        System.out.println("WriteArticleServiceImpl.write() 메서드 실행");
        articleDao.insert(article);
    }
 }
        ● MysqlArticleDao.java
 package kame.sping.chap01;

 public class MysqlArticleDao implements ArticleDao {
    @Override
    public void insert(Article article) {
        System.out.println("MysqlArticleDao.insert() 실행");
    }
 }
      ○ 스프링 설정 파일을 이용한 의존 관계 설정
        - WriteArticleServiceImpl 객체와 MysqlArticleDao 객체 사이의 의존 관계를 처리.
        ● 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-3.0.xsd"
>

    <bean name="writeArticleService" class="kame.spring.chap01.WriteArticleServiceImpl">
        <constructor-arg>
            <ref bean="articleDao"/>
        </constructor-arg>
    </bean>

    <bean name="articleDao" class="kame.spring.chap01.MysqlArticleDao">
    </bean>

 </beans>
 /* 코드로 표현한다면 */
 MysqlArticleDao articleDao = new MysqlArticleDao();

 WriteArticleServiceImpl writeArticleService = new WriteArticleServiceImpl(articleDao);
          □ <beans> 태그
            - 스프링 설정 파일의 루트 태그.
          □ <bean> 태그
            - 스프링은 각 객체를 빈(bean)으로 관리.
            - name 속성 : 빈의 이름, class 속성 : 생성될 객체의 클래스 타입.
          □ <constructor-arg> 태그
            - 생성자에 전달할 파라미터를 명시하기 위해 사용.
      ○ 스프링 컨테이너로부터 빈 객체 가져와 사용
        - 스프링을 이용하여 설정 파일을 로딩한 뒤, 설정 파일에 명시한 빈 객체를 사용.
        ● Main.java
          - 설정 파일로부터 BeanFactory를 생성하고 BeanFactory로부터 필요한 빈 객체를 가져와서 사용.
 package kame.spring.chap01;

 import org.springframework.beans.factory.BeanFactory;
 import org.springframework.beans.factory.xm.XmlBeanFactory;
 import org.springframework.core.io.ClassPathResource;
 import org.springframework.core.io.Resource;

 public class Main {
    public static void main(String[] args) {
        Resource resource = new ClassPathResource("applicationContext.xml");
        // Resource가 나타내는 XML 파일로부터 스프링 설정 내용을 로딩하여 빈 객체를 생성.
        // 빈 객체를 관리하는 컨테이너.
        BeanFactory beanFactory = new XmlBeanFactory(resource);
        WriteArticleService articleService = (WriteArticleService)beanFactory.getBean("writeArticleService");

        articleService.write(new Article());
    }
 }
 /* output */

 WriteArticleServiceImpl.write() 메서드 실행
 MysqlArticleDao.insert() 실행
          - BeanFactory 객체를 생성하면, BeanFactory로부터 빈 객체를 가져와 사용 가능.
          - BeanFactory.getBean(String name)을 사용하여 <bean>태그의 name 속성에 부여한 이름의 빈 객체를 구할 수 있다.
출저 : http://blog.naver.com/chocolleto/30085630331 


'Programming > JSP' 카테고리의 다른 글

Model&View helper pattern  (0) 2010/12/10
Dependency Injection과 스프링 프레임워크  (0) 2010/12/03
JSP구성요소  (0) 2010/12/03
동적쿼리  (0) 2010/12/02
페이지 알고리즘  (0) 2010/12/02
달력  (0) 2010/12/02

JSP구성요소

'Programming > JSP' 카테고리의 다른 글

Model&View helper pattern  (0) 2010/12/10
Dependency Injection과 스프링 프레임워크  (0) 2010/12/03
JSP구성요소  (0) 2010/12/03
동적쿼리  (0) 2010/12/02
페이지 알고리즘  (0) 2010/12/02
달력  (0) 2010/12/02
Return top

INFORMATION

안녕하세요.^-^* 초보개발자 입니다. puthathat@nate.com
 
a