티스토리 뷰

오브젝트와 의존관계

스프링의 핵심 철학은 객체지향 기술의 진정한 가치를 회복시키고, 그로부터 객체지향 프로그래밍이 제공하는 폭넓은 혜택을 누릴 수 있도록 기본으로 돌아가자는 것이다. 그래서 가장 관심을 많이 두는 대상은 오브젝트이다.


자바빈(JavaBean)

자바빈은 다음 두 가지 관례를 따라 만들어진 오브젝트를 가리킨다.

  • 디폴트 생성자 : 자바빈은 파라미터가 없는 생성자를 갖고 있어야 한다. 툴이나 프레임워크에서 리플렉션을 이용해 오브젝트를 생성하기 때문이다.

  • 프로퍼티 : 자바빈이 노출하는 이름을 가진 속성을 프로퍼티라고 한다. 프로퍼티는 set으로 시작하는 수정자 메소드(setter)와 get으로 시작하는 접근자 메소드(getter)를 이용해 수정 또는 조회할 수 있다.

리팩토링

기존의 코드를 외부의 동작방식에는 변화 없이 내부 구조를 변경해서 재구성하는 작업 또는 기술


인터페이스의 도입

인터페이스를 사용하는 이유

한 클래스에서 다른 클래스에 직접적인 구현체 대신 인터페이스를 넣어주는 방법을 사용하면, 인터페이스는 클래스들이 서로 긴밀하게 연결되어 있지 않도록 주입하는 클래스를 한 단계 추상화시켜서 중간에 추상적인 느슨한 연결고리를 만들어 준다. 추상화란 어떤 것들의 공통적인 성격을 뽑아내어 이를 따로 분리해내는 작업을 말한다.

인터페이스는 자신을 구현한 클래스에 대한 구체적인 정보는 모두 감춰버린다.

관계설정 책임의 분리

클래스 사이의 관계와 오브젝트 사이의 관계를 구분할 수 있어야 한다.

  • 클래스 사이의 관계 : 한 클래스가 인터페이스 없이 다른 클래스를 직접 사용하는 방식

  • 오브젝트 사이의 관계 : 런타임 시에 한쪽이 다른 오브젝트의 레퍼런스를 갖고 있는 방식


원칙과 패턴

개방 폐쇄 원칙(OCP, Open-Closed Principle)

클래스나 모듈은 확장에는 열려 있어야 하고 변경에는 닫혀 있어야 한다. 인터페이스를 통해 제공되는 확장 포인트는 확장을 위해 개방되어 있어야 한다. 반면 인터페이스를 이용하는 클래스는 자신의 변화가 불필요하게 일어나지 않도록 폐쇄되어야 한다.

높은 응집도와 낮은 결합도

  • 높은 응집도 : 변화가 일어날 때 해당 모듈에서 변하는 부분이 크다는 것을 말함. 즉, 변경이 일어날 때 모듈의 많은 부분이 함께 바뀐다는 말이 된다.

  • 낮은 결합도 : 하나의 오브젝트가 변경이 일어날 때 관계를 맺고 있는 다른 오브젝트에게 변화를 요구하는 정도가 낮다.

전략 패턴(Stratege Pattern)

자신의 기능 맥락(Context)에서, 필요에 따라 변경이 필요한 알고리즘을 인터페이스를 통해 외부로 분리시키고, 이를 구현한 클래스를 필요에 따라 바꿔서 사용할 수 있게 하는 디자인 패턴이다.


스프링의 IOC

용어 정리

  • 빈(bean) : 스프링이 IoC 방식으로 관리하는 오브젝트

  • 빈 팩토리(bean factory) : IoC를 담당하는 핵심 컨테이너. 빈을 등록, 생성, 조회, 리턴, 그 외에 부가적인 빈을 관리하는 기능을 담당

  • 애플리케이션 컨텍스트(Application Context) : 빈 팩토리를 확장한 IoC 컨테이너. Application Context는 BeanFactory를 상속. 기본적인 기능은 동일하지만 각종 부가 서비스를 추가로 제공한다.

  • 설정정보/설정 메타정보(configuration metadata) : 애플리케이션 컨텍스트 또는 빈 팩토리가 IoC를 적용하기 위해 사용하는 메타정보를 말한다.

  • 컨테이너(container) 또는 IoC 컨테이너 : IoC 방식으로 빈을 관리한다는 의미에서 애플리케이션 컨텍스트나 빈 팩토리를 컨테이너(container) 또는 IoC 컨테이너라고 한다.

  • 스프링 프레임워크 : IoC 컨테이너, 애플리케이션 컨텍스트를 포함해서 스프링이 제공하는 모든기능을 통틀어 말할 때 주로 사용.

애플리케이션 컨텍스트와 설정정보

빈의 생성과 관계설정 같은 제어를 담당하는 IoC 오브젝트를 빈 팩토리 또는 애플리케이션 컨텍스트라고 한다.

스프링이 빈 팩토리를 위한 오브젝트 설정을 담당하는 클래스라고 인식할 수 있도록 @Configuration 애노테이션을 추가한다.

오브젝트를 만들어 주는 메소드에는 @Bean 애노테이션을 붙여준다.

애플리케이션 컨텍스트를 사용했을 때 얻을 수 잇는 장점

  • 클라이언트는 구체적인 팩토리 클래스를 알 필요가 없다.

    • 다양한 오브젝트가 생기더라도 이를 일일이 알 필요없이 애플리케이션 컨텍스트를 이용하여 일관된 방식으로 원하는 오브젝트를 가져올 수 있다.
  • 애플리케이션 컨텍스트는 종합 IoC 서비스를 제공해준다.

    • 단순히 생성과 관계설정의 제공뿐 아니라 만들어지는 방식, 시점과 전략, 자동생성, 후처리, 정보의 조합, 설정방식의 다변화 등 다양한 부가기능을 제공한다.
  • 애플리케이션 컨텍스트는 빈을 검색하는 다양한 방법을 제공한다.

    • 애플리케이션 컨텍스트의 getBean() 메소드는 빈의 이름을 이용해 빈을 찾아준다.

싱글톤 레지스트리와 오브젝트 스코프

스프링은 여러 번에 빈을 요청하더라도 매번 동일한 오브젝트를 돌려준다. 기본적으로 싱글톤으로 만들기 때문이다. 애플리케이션 컨텍스트는 싱글톤을 저장하고 관리하는 싱글톤 레지스트리다. 일반적인 자바의 싱글톤과는 구현 방법이 다르다.

Java 싱글톤 구현방법

  • 외부 접근을 막기 위해 생성자를 private로 만든다.

  • 생성된 싱글톤 오브젝트를 저장하기 위해 자신과 같은 타입의 static field를 정의한다.

  • static factory method인 getInstance()를 통해 최초 호출 시에만 오브젝트를 만들고, 그 이후부터는 이미 만들어진 오브젝트를 돌려준다.

Java 싱글톤 패턴 구현 방식의 문제점

  • private 생성자를 갖고 있기 때문에 상속할 수 없다. 따라서 다형성도 적용할 수 없다.

  • 만들어지는 방식이 제한적이기 때문에 목 오브젝트 등으로 대체하기가 힘들어서 테스트하기가 힘들거나 방법에 따라 아예 불가능하다.

  • 서버환경에서는 싱글톤이 하나만 만들어지는 것을 보장할 수 없다.

  • 싱글톤의 사용은 static, 전역 상태를 만들 수 있기 때문에 객체지향 관점에서는 바람직하지 못하다.

싱글톤 레지스트리

직접 싱글톤 형태의 오브젝트를 만들고 관리하는 기능을 제공

  • 평범한 자바 클래스도 싱글톤으로 관리해준다.

  • 객체지향적인 설계 방식과 원칙, 디자인 패턴 등을 적용하는데 아무런 제약이 없다.

  • 싱글톤 방식으로 사용될 애플리케이션 클래스라도 public 생성자를 가질 수 있다. 따라서 테스트 환경에서 자유롭게 오브젝트를 만들 수 있고, 테스트를 위한 목 오브젝트로 대체하는 것도 가능하다.

  • 멀티스레드 환경에서 싱글톤이 사용되는 경우에는 내부 상태정보가 없는 Stateless 방식으로 만들어져야 한다. 따라서 스프링의 싱글톤 빈으로 사용되는 클래스를 만들 때는, 개별적으로 바뀌는 정보는 로컬 변수로 정의하거나, 파라미터로 주고 받으면서 사용하게 해야 한다.

빈의 스코프(Scope)

스프링 빈의 기본 스코프는 싱글톤이다. 경우에 따라서 다른 스코프를 가질 수 있다. 대표적으로 프로토타입(prototype) 스코프가 있다. 프로토타입은 싱글톤과 달리 컨데이너에 빈을 요철할 때마다 매번 새로운 오브젝트를 만들어준다. 그외에도 요청(request), 세션(session) 스코프도 있다.


의존관계 주입(DI)

IoC라는 용어는 매우 누슨하게 정의되서 폭 넓게 사용되는 용어이다. 때문에 스프링을 IoC 컨테이너라고만 해서는 제공하는 기능의 특징을 명확하게 설명 못한다. 그래서 의존관게 주입(Dependency Injection)이라는 좀 더 명확히 드러나는 이름을 사용하기 시작했다.

의존관계

A -------> B

A가 B에 의존한다는 것은 B가 변하면 그것이 A에 영향을 미친다는 것이다. 의존관계에는 방향성이 있다.

구체적인 클래스끼리 의존관계를 맺는 것 보다 인터페이스에 대해서만 의존관계를 만들어두면 인터페이스 구현 클래스와의 관계는 느슨해진다. 결합도가 낮고 변경에서 자유로워 진다.

런타임 의존관계(오브젝트 의존관계)

  • 인터페이스를 통해 의존관계를 갖는 경우, 런타임 시에 사용할 오브젝트가 어던 클래스로 만든 것인지 미리 알 수 없다.

  • 의존 오브젝트 : 런타임 시에 의존 관계를 맺는 대상, 즉 실제 사용 대상인 오브젝트

  • 의존관계 주입 충족 조건

    • 클래스 모델이나 코드에는 런타임 시점의 의존관계가 드러나지 않는다. 그러기 위해서는 인터페이스에만 의존하고 있어야 한다.
    • 런타임 시점의 의존관계는 컨테이너나 팩토리 같은 제 3의 존재가 결정한다.
    • 의존관계는 사용할 오브젝트에 대한 레퍼런스를 외부에서 제공(주입)해줌으로써 만들어진다.

의존관계 검색과 주입

스프링이 제공하는 IoC 방법에는 의존관게 주입만 있는 것이 아니다.

의존관계를 맺는 방법이 외부로부터의 주입이 아니라 스스로 검색을 이용하기 때문에 의존관계 검색이라고 불리는 것도 있다. 의존관계 검색은 자신이 필요로 하는 의존 오브젝트를 능동적으로 찾는다.

의존관계 검색은 런타임 시 의존관계를 맺을 오브젝트를 결정하는 것과 오브젝트의 생성 작업은 외부 컨테이너에게 IoC로 맡기지만, 이를 가져올 때는 메소드나 생성자를 통한 주입 대신 스스로 컨테이너에게 요청하는 방법을 사용한다.

메소드를 이용한 의존관계 주입

지금까지 의존관계 주입에 있어 생성자만 사용하였지만 이외의 방법도 있다.

  • 수정자 메소드를 이용한 주입

    • 일반적으로 수정자 메소드 setter를 이용한 방법
    • 핵심 기능은 파라미터로 전달된 값을 보통 내부의 인스턴스 변수에 저장하는 것이다.
    • 객체지향적인 방식에서는 회피해야 될 방법이다.
  • 일반 메소드를 이용한 주입

    • 여러 개의 파라미터를 갖는 일반 메소드를 DI용으로 사용할 수 있다.
    • 필요한만큼의 변수를 받을 수 있기 떄문에 한번에 모든 파라미터를 받아야하는 생서자보다는 장점을 갖고 있다.

참고

  • 토비의 스프링 3.1 Vol. 1 스프링의 이해와 원리

'Programming > 토비의 스프링 3.1' 카테고리의 다른 글

[토비의 스프링] AOP - 2  (0) 2020.07.01
[토비의 스프링] AOP - 1  (0) 2020.07.01
[토비의 스프링]예외  (0) 2020.03.23
[토비의 스프링]템플릿  (0) 2020.03.20
[토비의 스프링]테스트  (0) 2020.03.18
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/02   »
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
글 보관함