티스토리 뷰

Java/Spring

Spring IOC/DI 개념

싸드 2015. 7. 28. 15:43
눈아프신분들은 아래 링크 클릭해서 보세요.
정리되있는 주인장 블로그



Spring - IOC & DI

IOC(Inversion Of Control - 제어의역전)이란

말 그대로 간단하게 말하여 프로그램의 제어 흐름 구조가 바뀌는것이다.
일반적으로, main() 같은 프로그램이 시작되는 지점에서 다음에 사용할 오브젝트를 결정, 생성하고, 만들어진 오브젝트 내의 메소드를 호출하는 작업을 반복한다. 이런 구조에서는 각 오브젝트는 프로그램 흐름을 결정하거나 사용할 오브젝트를 구성하는 작업에 능동적으로 참여한다.
즉, 모든 작업을 사용하는 쪽에서 제어하는 구조!!

이에 반하여 IOC는 제어 흐름의 개념을 거꾸로 뒤집는다.
오브젝트는 자신이 사용할 오브젝트를 스스로 생성하거나 선택하지 않느다. 그리고 자신이 어떻게 만들어지고 어디서 사용되는지 알 수 없다. 모든 제어 권한을 자신이 아닌 다른 대상에게 위임하는 것이다. 프로그램의 시작을 담당하는 main() 같은 엔트리 포인트를 제외하면 모든 오브젝트는 이런 방식으로 위임받은 제어 권한을 갖는 특별한 오브젝트에 의해 결정되고 만들어지는 것이다.

    - 작업을 수행하는 쪽에서 Object를 생성하는 제어 흐름의 개념을 거꾸로 뒤집는다.
    - IOC에서는 Object가 자신이 사용할 Object를 생성하거나 선택하지 않는다.
    - 또한 Object는 자신이 어떻게 생성되고 어떻게 사용되는지 알 수 없다.
    - 모든 Object는 제어 권한을 위임받는 특별한 Object에 의해서 만들어 지고 사용된다.

IOC 구현 방법

  • DL(Dependency LookUp) - 의존성 검색

    저장소에 저장되어 있는 빈(Bean)에 접근하기 위해 개발자들이 컨테이너에서 제공하는 API를 이용 사용하고자 하는 빈을 Lookup 하는것
  • DI(Dependency Injection) - 의존성 주입

    각 계층 사이, 각 클래스 사이에 필요로 하는 의존관계를 컨테이너가 자동으로 연결해주는것
    각 클래스 사이의 의존관계를 빈 설정(Bean Definition) 정보를 바탕으로 컨테이너가 자동으로 연결해주는 것
    DL 사용시 컨테이너 종속성이 증가하여, 이를 줄이기 위하여 DI를 사용

    Setter Injection

  • 인자가 없는 생성자나 인자가없는 static factory 메소드가 bean을 인스턴스화 하기 위하여 호출된 후 bean의 setter 메소드를 호출하여 실체화 하는 방법.
  • 객체를 생성 후 의존성 삽입 방식이기에 구현시에 좀 더 유연하게 사용 가능
  • 세터를 통하여 필요한 값이 할당되기 전까지 객체 사용 불가
  • Spring FW 빈설정 파일에서 property 사용
java code

public class Service{
    private Collaborator collaborator;

    @required
    public void setCollaborator(Collaborator c) {
        this.collaborator = c;
    }
}

하지만 위와 같이 셋터 메소드로 인젝션 주입시에도 Collaborator 변수가 널이라면?

public class Service implements InitializingBean {

  private Collaborator collaborator;

  public void setCollaborator(Collaborator c) {
    this.collaborator = c;
  }

  // from the InitializingBean interface
  public void afterPropertiesSet() {
    if (collaborator == null) {
      throw new IllegalStateException("Collaborator must be set in order for service to work");
    }
  }
}

위와 같인 afterPropertiesSet 메소드가 존재 할 경우 셋터에 값을 선언 안해주고 사용시 익셉션이 발생할 수 있다.
하지만 내가 알기론 스프링에 해당 객체위에 예전에는 @Required 어노테이션을 붙으주면 스프링에서 빈으로 등록해 주기 때문에 에러가 발생하지 않는걸로 알고있다. 3.0이상부터인가 @Autowired 어노테이션이 막강해지면서 위와 같은 문제는 없는걸로 알고 있다. ( 잘못된 지식이라면 댓글로 설명 부탁드립니다.)

xml config

<bean id="authenticator" class="com.mycompany.service.AuthenticatorImpl"/>

<bean id="accountService" class="com.mycompany.service.AccountService">
  <property name="authenticator" ref="authenticator"/>
</bean>

Constructor Injection

  • 생성자를 이용하여 클래스 사이의 의존 관계를 연결
  • 생성자에 파라미터를 지정함으로써 생성하고자 하는 객체가 필요로 하는 것을 명확하게 알 수있다.
  • Setter메소드를 제공하지 않음으로 간단하게 필드를 불변 값으로 지정 가능
  • 생성자의 파라미터가 많을 경우 코드가 복잡해짐
  • 조립기 입장에서는 생성의 순서를 지켜야 하기에 상당히 불변파다
  • Spring 프로엠 워크의 빈 설정 constructor-arg 사용
java code
public class Service {

  public Collaborator collaborator;

  // constructor with arguments, you *have* to
  // satisfy the argument to instantiate this class
  public Service(Collaborator collaborator) {
    this.collaborator = collaborator;
  }
}

위 주입방식에는 주입되는 collaborator 가 널일경우 의존성 주입 후 코드 생성시 익셉션이 발생 할 수 있다.

public Service(Collaborator collaborator) {
  if (collaborator == null) {
    throw new IllegalArgumentException("Collaborator cannot be null");
  }
  this.collaborator = collaborator;
}

위와 같이 변경시 미리 익셉션을 잡아주면 좀더 완벽한 코드가 된다.

xml code

<bean id="authenticator" class="com.mycompany.service.AuthenticatorImpl"/>

<bean id="accountService" class="com.mycompany.service.AccountService">
  <constructor-arg ref="authenticator"/>
</bean>

IOC 용어

bean

  • 스프링에서 제어권을 가지고 직접 만들고 관계를 부여하는 오브젝트
    자바빈, EJB의 빈과 비슷한 오브젝트 단위의 애플리케이션 컴포넌트를 말함. 하지만 스프링을 사용하는 애플리케이션에서 만들어지는 모든 오브젝트가 빈은 아니다. 스프링의 빈은 스프링 컨테이너가 생성과 관계설정, 사용들을 제어해주는 오브젝트를 가리킨다.

bean factory

  • 스프링의 IOC를 담당하는 핵심 컨테이너
    빈을 등록/생성/조회/반환/관리함. 보통은 bean factory를 바로 사용하지 않고 이를 확장한 application context를 이용한다. beanFactory는 bean factory가 구현하는 Interface. (getBean() 등으로 구현됨)

application Context

  • bean factory를 확장한 IOC 컨테이너
    빈의 등록/생성/조회/반환/관리의 기능은 bean factory와 같지만, 여기에 spring의 각종 부가서비스를 추가 제공.
    ApplicationContext는 application context가 구현해야하는 interface이며, BeanFactory를 상속한다.

configuration metadata(설정정보/ 설정 메타정보)

  • application context 또는 bean factory가 IOC를 적용하기 위해 사용하는 메타 정보
    스프링의 설정 정보는 컨테이너에 어떤 기능을 세팅하거나 조정하는 경우에도 사용하지만 주로 bean을 생성/구성하는 용도로 사용

    <!-- Enables the Spring MVC @Controller programming model -->
      <annotation-driven />
    
      <context:component-scan base-package="pe.kr.imjehoon" />
    

    위와 같은 코드 한줄이면 3.0 부터는 스프링이 자동으로 해당 패키지 아래 클래스들을 스캔하며 어노테이션이 붙은 클래스(@Controller, @service, @들을 자동으로 빈으로 등록해준다… 참으로 편리해졌다. 물론 데이터 소스 등 은 따로 xml설정 파일에서 하는것이 좀 더 편리하다.
    하지만 어떤 방식으로 스프링이 셋을 해주는지 기초를 알고 가는게 중요한데 나도 아직 기초 부분을 자세히 모르고 편리하니까 쓰고 있다. 그래서 DI에 대한 개념 을 정리하는 중이다.(스프링은 설정이 반이다..ㅠ)

container(IOC container)

  • IOC방식으로 bean을 관리한다는 의미에서 bean factory나 application context를 가리킨다.
    (spring container = application container) application context는 그 자체로 ApplicationContext 인터페이스를 구현한 오브젝트를 가리키기도 하는데, 하나의 애플리케이션에 보통 여러개의 ApplicationContext Object가 만들어진다. 이를 통틀어서 spring container라고 부를 수 있다. 간단하게 객체를 관리하는 컨테어니, 컨테이너에 객체를 담아두고, 필요할때에 컨테이너로부터 객체를 가져와서 사용할 수 있도록 해줌.

'Java > Spring' 카테고리의 다른 글

SPRING AOP개념  (0) 2015.07.28
Spring 한글 깨짐 설정  (0) 2015.07.28
Spring WebSocket sockJS 채팅 예제  (0) 2015.07.23
Spring locale 나라 별 코드  (0) 2014.04.14
Cookie 생성/ 설정/ 삭제  (0) 2012.08.19
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함