Skip to content

스프링 핵심 원리 ‐ 기본편 : 섹션 4~ 섹션 6

minahkim03 edited this page May 14, 2024 · 1 revision

섹션 4: 스프링 컨테이너와 스프링 빈

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

  • AplicationContext -> 스프링 컨테이너라고 하며 인터페이스임.

  • new AnnotationConfigApplicationContext(AppConfig.class)AplicationContext인터페이스의 구현체임.

  • 과정: 스프링 컨테이너 생성 -> AppConfig.class의 정보를 활용해 스프링 빈 등록 -> 의존관계 준비 후 의존관계를 주입함.

  • 빈 조회 기본: .getBean(이름(생략 가능), 타입)

  • 동일한 타입의 빈이 두개 이상 존재할 때: .getBeansOfType(타입) 을 하면 이름을 key로 갖고 빈을 value로 갖는 map이 생성됨.

  • 상속 관계의 빈 조회: 부모를 조회하면 모든 자식 빈이 다 조회됨. 특정 하위 타입 조회 가능하지만 비추천.

  • BeanFactory: 스프링 컨테이너의 최상위 인터페이스, ApplicationContext가 이를 상속함. 스프링 빈을 관리하고 조회하며 getBean() 등을 제공함.

  • ApplicationContext: BeanFactory가 제공하는 기능 + MessageSource를 활용한 국제화 기능, 환경변수, 애플리케이션 이벤트, 편리한 리소스 조회

섹션 5: 싱글톤 컨테이너

  • 스프링 없는 DI 컨테이너인 AppConfig는 요청이 올 때 마다 객체 생성 -> 메모리 낭비가 심함 -> 객체를 하나만 생성하고 공유하도록 하는 싱글톤 패턴 차용

  • 싱글톤 패턴: 객체 인스턴스가 하나만 생성되도록 하는 디자인 패턴 -> static 영역에 객체 instance를 미리 생성하고 getInstance로만 조회할 수 있게함 -> 스프링이 자체적으로 싱글톤 패턴을 사용함 (싱글톤 컨테이너) : 지저분한 코드 등 단점을 모두 극복

  • 싱글톤 객체는 무상태로 설계 해야함. -> 가급적 읽기만 가능, 값을 변경할 수 없게함.

  • 의존관계로 인해 AppConfig 안에서 같은 객체가 여러번 호출 되어도 객체는 하나만 존재함 -> 바이트 코드 조작 라이브러리를 사용하여 AppConfig를 상속한 다른 클래스를 만들고 스프링 빈으로 등록함 (@Configuration)

섹션 6: 컴포넌트 스캔

  • @Bean으로 직접 등록하는 방식 대신 스프링은 컴포넌트 스캔이라는 자동으로 스프링 빈을 등록하는 기능을 제공함.
  • 모든 스프링 빈 클래스 위에 @Component 선언. 의존 관계 주입은 @Autowired: 스프링 컨테이너에서 해당 타입의 스프링 빈을 찾아서 주입함.
  • 컴포넌트 스캔 시에 탐색할 패키지의 시작 위치를 지정할 수 있음. 지정하지 않으면 @ComponentScan이 붙은 클래스의 패키지 부터 탐색 시작.

@ComponentScan(basePackages = "hello.core.member")

  • 프로젝트 시작할 때 구조의 최상위에 AppConfig와 같은 메인 설정과 @ComponentScan을 두는 것이 좋음. @ComponenetScan은 @SpringBootApplication에 포함.
  • 컴포넌트 스캔을 할 때 @Component, @Controller, @Service, @Repository, @Configuration을 모두 스캔함.

`@ComponentScan(

        includeFilters = @Filter(type = FilterType.ANNOTATION, classes =
                MyIncludeComponent.class),
        excludeFilters = @Filter(type = FilterType.ANNOTATION, classes =
                MyExcludeComponent.class)

)`

  • ANNOTATION -> 디폴트이기 때문에 생략 가능.
  • includeFilters는 거의 사용할 일이 없고 excludeFilters는 간혹 사용.
  • 수동 등록 빈과 자동 등록 빈이 이름이 겹칠 때에는 수동 빈이 자동 빈을 오버라이딩 하여 우선순위를 가짐. -> 의도하지 않은 경우가 대부분이므로 최근에는 오류가 나도록 바꿈.