스프링 핵심 원리 2장

wook2·2021년 10월 16일
0
post-thumbnail

이전 1장에서는 OCP와 DIP를 만족시키기 위해 스프링 프레임워크를 사용한다고 설명했다. 하지만 기존에 만들었던 AppConfig역시 OCP와 DIP를 만족하는 컨테이너 역할을 충실히 수행한다. 2장에서는 스프링을 사용하면서 얻는 이점이 무었이 있는지, 어떠한 방식으로 관리하는지 알아보았다.

스프링 적용하기

기존에 만들었던 AppConfig 클래스에 @configuration과 @Bean만 붙여주면 스프링 빈에 등록되어 사용할 수 있다. 스프링 컨테이너를 통해 필요한 객체를 찾을 수 있는데, applicationContext.getBean() 메소드로 찾을 수 있다.

그렇다면 이렇게 붙여서 사용하면 기존에 만들었던 코드와 어떤점이 좋고 뭐가 다른데? 라고 의문이 들수 있다.
물론 이와 같이 수동으로 configuration을 등록하는 방식보단 컴포넌트 스캔을 통한 자동 의존주입 방식을 스프링에서 주로 사용하는 것으로 보인다.
스프링을 사용하는 장점을 앞으로 설명할 것이다.

스프링 컨테이너 생성

ApplicationContext ac =new AnnotationConfigApplicationContext(AppConfig.class);

ApplicationContext를 스프링 컨테이너라고 부른다. AnnotationConfigApplicationContext는 ApplicationContext인터페이스의 구현체로, 구현체 안에 만들었던 AppConfig를 인자로 넘겨주었다.

컨테이너에 등록된 빈 조회

  • 모든 빈 출력하기
    1.ac.getBeanDefinitionNames() : 스프링에 등록된 모든 빈을 조회한다.
    2.ac.getBean() : 빈(Bean)객체를 조회한다.

  • 어플리케이션 빈 출력하기
    스프링 내부에서 사용하는 빈은 getRole()으로 구분할 수 있다.
    빈이름.ROLE_APPLICATION은 일반적으로 사용자가 정의한 빈이다.

  • 타입으로 조회시 동일한 타입이 있는 경우
    타입으로 조회시 동일한 타입이 있을 때, 오류가 발생한다.
    ac.getBeansOfType()은 해당 타입의 모든 빈을 조회할 수 있다.

BeanFactory 와 ApplicationContext

BeanFactory는 스프링 컨테이너에서 최상위 인터페이스이다.
스프링 빈을 관리하고 조회하는 역할을 담당한다. getBean()등의 메서드를 제공한다.

ApplicationContext는 BeanFactory기능을 모두 상속받아서 제공한다. ApplicationContext는 BeanFactory외에 여러가지 인터페이스들을 상속받아 다양한 기능을 제공하게 도와준다.

Bean설정 메타정보

스프링 컨테이너는 다양한 형식의 설정정보를 받을 수 있도록 설계되어 있다.
ex) java, xml, groovy,...

스프링은 단지 BeanDefinition의 정보만을 이용하는데, 자바로 빈을 설계하던지, XML로 설계하던지, 단지 규격에만 맞추어 설계하면 되니, BeanDefinition만 보면 된다.

싱글톤 컨테이너

스프링을 사용하는 가장 큰 이유에는 싱글톤 컨테이너를 항상 유지시켜준다는 점이 있다.
기존에 만들었던 AppConfig를 순수 자바로 실행한다고 생각하고 로직을 따라가보자.
memberService를 만드는데 new memberRepository를 통해 객체를 생성하고, orderService를 만드는데 new memberRepository를 통해 객체를 생성한다.
그렇다면 웹 어플리케이션이라고 생각해보면, 사용자의 요청마다 새로운 객체를 생성하여 넘겨주는 것이다.
그렇기 때문에 해당 객체가 단 한번만 생성되고, 공유되도록 싱글톤 패턴을 사용하도록 설계하면 된다.

싱글톤 패턴

싱글톤 패턴은 클래스의 인스턴스가 단 한개만 생성되도록 보장하는 디자인 패턴이다. 그렇기 때문에 private을 통해 객체가 두개이상 생성되지 않도록 막아야 한다.

public class SingletonService {
 private static final SingletonService instance = new SingletonService();
 public static SingletonService getInstance() {
 return instance;
 }
 private SingletonService() {
 }
 public void logic() {
 System.out.println("싱글톤 객체 로직 호출");
 }
}

싱글톤 객체를 static으로 선언한과 동시에 private으로 생성자를 선언함으로써 외부에서 생성자를 통해 객체를 생성하지 못하게 막았다.

이러한 싱글톤 패턴의 문제점은 일단 클라이언트가 구체 클래스에 의존하게 된다는 점이다. 또한 여러가지 싱글톤 패턴의 문제점들이 있다.

싱글톤 컨테이너의 장점

싱글톤 컨테이너는 싱글톤 패턴을 적용하지 않아도 객체 인스턴스를 싱글톤으로 관리한다. 스프링 컨테이너는 이러한 싱글톤 컨테이너를 사용함으로써, 싱글톤 패턴을 위한 지저분한 코드가 필요 없을뿐 아니라, DIP, OCP, private등의 문제를 해결할 수 있다.

싱글톤 컨테이너 설계의 주의점

싱글톤 컨테이너는 결국 객체를 하나 생성하고 하나를 관리하는 방식인데, 이 객체는 상태를 유지하게 생성하면 안된다.
클라이언트에 의존적인 필드가 있거나, 클라이언트가 값을 바꾼다거나 하는 방식은 후에 어디서 어떤것이 바뀌었는지 확인하기가 매우 어렵고, 가급적 읽기만 이용하는 방식만 사용해야 한다.

profile
꾸준히 공부하자

0개의 댓글