티스토리 뷰

Java/spring

Spring DI

LichKing 2016. 2. 23. 16:01

현재 널리 사용되고있는 자바 프레임워크인 Spring의 핵심 가치중 하나는 IoC라 할 수 있다. IoC는 Inversion of Control의 약자로 번역하면 제어의 역전이라는 뜻인데 스프링 컨테이너를 의미한다. 간단하게 말하면 개발자들이 직접 new 연산자를 통해 생성하던 객체제어를 스프링 컨테이너가 가져감으로서 애플리케이션 내에서 사용되는 객체의 생성과 소멸(LifeCycle)을 프레임워크가 담당하겠다는 것이다. 그리고 그런 IoC를 구현하기위해 도입된게 DI인데 IoC는 공부를 하면 할수록 너무 방대한 개념인것같아 아직 내가 다루기엔 무리가 있는듯해 DI에 대해서만 포스팅을 해보겠다.

DI는 Dependency Injection의 약자로 의존성 주입이라는 말로 번역된다.

여기서 의존성이란 간단하게 new 연산자라고 생각하면 되는데 일단 의존성에 대해 알고 넘어가자. 자바는 객체지향 언어로서 각각의 객체들에게 일정한 역할을 위임하고 그 객체들의 협력을 통해 문제를 해결하는 프로그래밍 언어이다. 보통 자바개발을 할때 한 메서드내에서 모든 일을 처리하고자 하는 경우가 많은데 엄밀히보면 그건 객체 지향적 코딩이라고 할수는 없다. 객체지향언어인 자바를 이용해 절차지향적 코딩을 하고있는 것이다.

여튼 객체들의 협력을 통해 문제를 해결하는것이 객체지향언어이기때문에 객체지향적으로 코딩을 하다보면 여기저기서 객체들을 생성하고 해당 객체의 메서드를 호출하게된다. 그리고 호출하는 객체는 자신이 호출하는 객체의 메서드에 의존하게 되는데 이것이 의존성이다.


class A{

  public void method(){

    B b = new B();


    b.method();  //A클래스는 B클래스에 의존한다. B클래스에 수정사항이 생기면 A클래스도 영향을 받는다.

  }

}


그렇다면 의존은 어떤 문제를 야기하게 될까? 소프트웨어 개발에 있어서 요구사항은 언제든 변하고, 추가되기 마련이다. 구현해놓은 A, B 클래스를 소프트웨어 폐기전까지 전혀 수정하지않는다면 아무런 문제가 없지만 그건 개발자들의 희망사항에 불과하다. B클래스에 대해서 추가요구사항이 들어오게되면 이미 잘 돌아가고있던 B 클래스를 수정해야하고 B 클래스를 수정하게되면 그 B 클래스에 의존하고있고 A 클래스에도 어떤식으로든 영향이 가게된다. 그때문에 사이드이펙트를 우려해야하고 결국 변화와 확장에 매우 취약한 환경이 되는것이다. 일단 이걸 해결하기위해 자바의 장점인 다형성을 활용해보자


class A{

  public void method(){

    Inter b = new B();  //Inter는 인터페이스이고 B 클래스는 Inter를 구현한 클래스이다.


    b.method();

  }

}


객체 참조를 구현클래스가 아닌 인터페이스를 통해 하고있다. 차후 B 클래스를 동일한 인터페이스를 구현한 C 클래스로 교체해야하는 상황이 오면 객체 생성부분만 new C(); 로 수정하면 된다. 또한 인터페이스로 '규약'을 해놨기때문에 차후 A 클래스에서 호출해야하는 객체가 변경될경우 Inter 인터페이스를 구현하게끔 만들면 추가적인 클래스를 생성하는 경우에도 객체생성 부분만 수정하면 수정해야할 부분이 크게 없다.

단순히 인터페이스 하나만 사용한것인데 첫번째 예제에 비해 확장성이 크게 좋아졌다. 그러니 우리모두 인터페이스를 애용해야한다. 리팩토링이나 디자인패턴도 결국은 다 인터페이스로부터 시작된다.

확장성이 좋아지고 소스가 매우 유연해졌지만 여튼 수정사항이 들어오면 A클래스를 건드려야한다. 유지보수에 용이한 소스를 짜는 기법중 하나는 변경되는 부분과 변경되지않는 부분을 분리하는 것이다. 객체 생성 부분을 분리해보자.


class A{

  public void method(){

    Factory f = new Factory();


    Inter b = f.getInstance();


    b.method();

  }

}


객체생성부분을 팩토리로 바꿨다. 이제 b가 참조해야하는 객체를 바꿀일이 생기면 팩토리소스만 수정하면된다. 변경되는 부분과 변경되지않는 부분을 분리한것이다. 또한 팩토리에서 객체를 생성하여 객체를 주입하니 이또한 DI라고 할수있겠다. 스프링은 이것을 설정파일(xml) 혹은 애노테이션을 통해 해결함으로서 의존성을 주입해주고있다.


class A{

  public void method(){

    @Autowired

    Inter b;


    b.method();

  }

}


간단한 방법으로 의존성을 주입해주기때문에 유지보수에도 용이하고 확장하기도 용이한 소스가 됐다. 또한 애노테이션으로 주입하는 객체의 생성을 스프링 컨테이너가 해주는것이기때문에 위에서 IoC에 대한 언급이 필요했던 것이다.

글을 쓰면서도 아직 많은 부분이 부족한것같다. 좀더 공부하고 계속 보충해야겠다...

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

Spring Bean 초기화/소멸  (0) 2017.11.17
static factory method를 이용한 spring bean 생성  (4) 2017.11.16
Spring Converter  (0) 2017.03.12
List, Map Spring Bean 생성  (0) 2017.02.24
intellij spring mvc 설정  (0) 2016.07.20
Spring DI  (0) 2016.02.23
댓글
댓글쓰기 폼