본문 바로가기

WINK-(Web & App)/Spring Boot 스터디

[2024 Spring Boot 스터디] 유태근 #2 주차 - 스프링 컨테이너와 스프링 빈

반응형

 

 

스프링 컨테이너와 스프링 빈

전 주차때 스프링 컨테이너에 객체를 스프링 빈으로 등록하고, 스프링 컨테이너에서 스프링 빈을 찾아서 사용하는 방식으로 변경하는 작업으로 마무리했다.

스프링 컨테이너의 특성 및 역할

  • 생성할 때는 구성 정보를 지정해주어야 한다.
  • 파라미터로 넘어온 설정 클래스 정보를 사용해서 스프링 빈을 등록한다. @Bean 으로 직접 등록해주면 해당 함수명이 빈의 이름으로 등록된다.
  • 설정 정보를 참고해서 Bean들의 의존관계를 주입한다.

스프링 빈에는 Role에 따라 2가지로 나눌 수 있다.

  1. ROLE_APPICATION : 우리가 직접 정의한 빈
  2. ROLE_INFRASTRUCTURE : 스프링 내부에서 사용하는 빈

스프링 빈 조회

  • 스프링 컨테이너에 등록된 스프링 빈은 이름, 타입, 구현 타입 등으로 조회할 수 있다.
  • 조회시 동일 이름의 동일한 타입의 빈이 둘 이상 있으면, 중복 오류인 NoUniqueBeanDefinitionException이 발생한다.
  • 부모 타입으로 조회시 자식이 둘 이상 있으면 중복 오류가 발생하기 때문에 빈 이름을 지정하면 된다.

실무에서는 빈을 직접 조회할 일은 거의 없지만 가끔 순수한 자바 어플리케이션에서 스프링 컨테이너를 생성해서 써야 할 일이 있을 수 있다.

 

BeanFactory

: 스프링 컨테이너의 최상위 인터페이스로 빈을 관리하고 조회하는 역할을 담당한다.

 

ApplicationContext

: BeanFactory 의 모든 기능을 상속받아서 제공하고 추가로 편리한 부가 기능을 제공한다.

  • BeanFactory말고 ApplicationContext를 사용하면 된다.

Application Context의 편리한 부가 기능

  1. 메시지 소스를 활용한 국제화 기능 및 다국어 처리
  2. 환경변수 처리
    • 로컬 : 본인 PC 환경
    • 개발 : 테스트 서버
    • 스테이지 : 운영과 밀접한 테스트 서버
    • 운영 : 프로덕션 환경
  3. 이벤트 발행 및 구독 서비스 등 애플리케이션 이벤트 제공
  4. 외부 파일 및 리소스를 편리하게 조회

추가로 XML이나 스프링 빈 설정 메타 정보인 BeanDefinition으로 스프링 빈을 등록하거나 설정할 수 있지만 실무에서 거의 사용하지 않는다. (스프링이 다양한 기능을 제공해준다 정도만 기억)

싱글톤 컨테이너

스프링 없는 DI 컨테이너는 고객의 요청마다 객체를 새로 생성해서 메모리 낭비가 심하다.

-> 해당 객체를 1개만 생성하고 공유하도록 설계해서 효율적으로 재사용할 수 있다. (싱글톤 패턴)

싱글톤 구현 방법

1. static으로 미리 객체를 생성해두고 생성자는 private으로 막고 getInstance()를 통해서만 객체에 접근할 수 있도록 설정

2. 지연 생성

public class Singleton { 
	
	private static Singleton instance; // 하나의 인스턴스

	private Singleton() {} // 외부에서 인스턴스 생성못하게 private 생성자 사용

	public static Singleton getInstance() { // 함수를 통한 인스턴스 호출
		if (instance == null){
			instance = new Singleton(); 
		} 
		return instance; 
	} 
}

3. Thread safe 방식

public class ThreadSafeSingleton {

    private static ThreadSafeSingleton instance;

    private ThreadSafeSingleton(){}

    public static synchronized ThreadSafeSingleton getInstance() {
        if (instance == null) {
            instance = new ThreadSafeSingleton();
        }
        return instance;
    }

}
//double-checked
public static ThreadSafeSingleton getInstanceUsingDoubleLocking() {
    if (instance == null) {
        synchronized (ThreadSafeSingleton.class) {
            if (instance == null) {
                instance = new ThreadSafeSingleton();
            }
        }
    }
    return instance;
}

4. Enum 방식

public enum EnumSingleton {

    INSTANCE;

    public static void doSomething() {
        // do something
    }
}

 

싱글톤 방식의 주의점

  • 하나의 같은 인스턴스를 공유하기 때문에 무상태(stateless)로 설계해야 한다.
  • 외부에 의존적인 필드가 있으면 안된다.
  • 외부에서 값을 변경할 수 없도록 한다.
  • 내부에서도 가급적 읽기만 가능하게 한다.

스프링 싱글톤 컨테이너

  • 싱글톤 패턴을 직접 적용하지 않아도, 알아서 인스턴스를 싱글톤으로 관리한다.
  • 스프링 컨테이너는 싱글톤 컨테이너 역할을 한다.
  • DIP, OCP 등 싱글톤 패턴의 모든 단점을 해결하면서 유지할 수 있다.

스프링 컨테이너는 스프링 빈이 싱글톤이 되도록 보장해준다.

  • @Bean이 붙은 메서드를 확인해서 이미 동일한 스프링 빈이 존재하면 존재하는 빈을 반환하고, 없으면 새로 스프링 빈을 생성해서 등록한다.

@Bean만 사용해도 스프링 빈으로 등록되지만, 싱글톤을 보장하지는 않는다.

-> 스프링 설정 정보는 항상 @Configuration 사용한다.

반응형