토비의 스프링 1장

Bean과 Application Context

Bean은 스프링이 제어권을 가지고 직접 만들고 관계를 부여(=IoC방식으로 관리)하는 오브젝트다.

EJB에서 말하는 빈과 비슷하게 애플리케이션 컴포넌트를 말하지만 IoC가 적용된 형태라고 보면 된다.

주의 : 스프을 사용하는 애플리케이션에서 만들어지는 모든 오브젝트가 빈이 아니다

제어를 담당하는 IoC 오브젝트는 빈 팩토리라고 부른다. 이 빈 팩토리를 상속해서 확장된게 Application Context 인데 같은 뜻으로 쓸 때가 많다. IoC 담당 일찐 컨테이너라고 외우자.

빈 팩토리는 빈 생성 및 관리의 뜻이 강하고 어플리케이션 컨텍스트는 전반적인 구성요소의 제어 작업을 담당하는 IoC 엔진의 의미가 부각된다. 스프링의 부가 서비스를 더 도와줄 수 있다.


기존 팩토리와 빈 팩토리의 차이

@Configuration
public class LinkFactory{
  @Bean
  public LinkDao linkDao(){
    return new LinkDao(petMaker());
  }

  @Bean
  public AnimalInfo petMaker(){
    return new catInfoMaker();
  }
}
LinkDao link = context.getBean("linkDao", LinkDao.class);

//getBean은 어플리케이션 컨텍스트가 관리하는 오브젝트를 이름으로 요청하는 메소드
//여기서 context는 Application Context

@Bean : 오브젝트를 만들어주는 메소드를 지정

@Configuration : 빈 팩토리를 위한 오브젝트 설정을 담당하는 클래스 (application의 청사진을 담은 설정정보)

이렇게만 보면 기존의 팩토리 방식과 어떤 차이가 생기는지 잘 모르겠다. 하지만 내부 동작 방식에서는 훨씬 좋다는걸 알 수 있다.

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

복잡한 애플리케이션이 될수록 오브젝트마다 팩토리 클래스도 계속 추가되는 불편함이 있지만 애플리케이션 컨텍스트는 일관된 방법으로 오브젝트를 가져올 수 있다.

2. 종합 IoC 서비스, 즉 빈에게 더 도움되는 기술을 제공하거나 부가 기능을 더 사용할 수 있다

3. 빈 검색을 여러 방법으로 할 수 있다.


헷갈리는 용어

Container = IoC Container = Bean factory = Application Context = Spring Container

다 비슷한 말이라고 보면 된다.

여기서 bean factory만 조금 더 빈의 CRUD를 해준다는 기능적인 면을 부각시킨 것이라 한다.


Singletone Registry

기존 팩토리 방식과 가장 중요한 차이점이 여기서 나온다!

오브젝트 팩토리

return new LinkDao(petMaker());

어플리케이션 컨텍스트

context.getBean("linkDao", LinkDao.class);

LinkDao를 여러번 가져올때마다 불려지는 이 호출 구문 두개가 가져오는 차이점이 무엇일까?

바로 new에 그 차이가 있다. 첫번째는 new로 매번 새로운 객체를 가지고 오지만 두번째는 매번 동일한 객체를 돌려준다.

여기서 얻을 수 있는 결론은 어플리케이션 컨텍스트가 싱글톤을 저장하고 관리하는 싱글톤 레지스트리라는 것이다.

Spring은 엔터프라이즈 시스템에서 비롯된 기술이기에 서버 환경에서 사용될 때 가치가 있다. 그리고 초기의 서버 환경은 하나의 서버가 온갖 복잡한 비즈니스 로직과 계층 구조를 처리해야 했다. 이런 서버 환경에서 매번 요청 때마다 새로운 오브젝트를 만들어낸다면 서버의 부하가 반드시 걸리게 될것이다.

그러면 싱글톤 패턴을 쓰는게 무조건 좋은게 아닌가?

자바의 싱글톤 패턴은 이러한 특징을 가진다.

  • private 생성자

  • 생성된 인스턴스를 저장할 수 있는 자신과 같은 타입의 static 필드 변수

  • getInstance라는 static 팩토리 메소드를 만들고 최초 호출 한번만 만들어지게 한다.

특징들은 또한 이런 문제가 생긴다.

  • private 생성자때문에 상속이 불가하고 객체지향의 장점인 다형성을 적용 불가하다.

  • 테스트가 힘들다.(초기화 과정이 어려워서)

  • static 메소드로 언제든 싱글톤은 전역 상태를 가질 수 있기에 멀티 스레드 환경에서의 싱글톤은 상태 관리에 주의를 기울여야 한다.

그래서 thread-unsafe한 객체들에는 싱글톤을 쓰지않고 db 작업관련된것들은 독립적인 공간을 사용하는 로컬변수를 통해 쓴다.

아무튼!

싱글톤의 단점때문에 스프링은 직접 싱글톤 형태로 빈을 만들고 관리한다. 그리고 빈의 생성과 적용되는 범위를 빈의 스코프라고 한다. 기본은 싱글톤이지만 매번 새로운 오브젝트를 만들어주는 프로토타입 스코프도 있다.