Spring

spring container, spring bean에 대해서 알아보자

hwlee9905 2024. 1. 4. 13:11
spring container
  • ApplicationContext 를 스프링 컨테이너라 한다.
  • spring container는 @Configuration 이 붙은 AppConfig 를 설정(구성) 정보로 사용한다. 여기서 @Bean 이 라 적힌 메서드를 모두 호출해서 반환된 객체를 스프링 컨테이너에 등록한다. 이렇게 spring container 에 등록된 객체를 spring bean이라 한다.
  • spring bean은 @Bean 이 붙은 메서드의 명을 spring bean의 이름으로 사용한다.
  • spring container 는 설정 정보를 참고해서 의존관계를 주입(DI)한다.

 

//스프링 컨테이너 생성
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
  • ac.getBeanDefinitionNames() : 스프링에 등록된 모든 빈 이름을 조회한다. 
  • ac.getBean() : 빈 이름으로 빈 객체(인스턴스)를 조회한다
    • ac.getBean(beanName, type)
    • ac.getBean( type )
  • spring이 내부에서 사용하는 빈은 getRole() 로 구분할 수 있다.
  • ROLE_APPLICATION : 일반적으로 사용자가 정의한 빈
  • ROLE_INFRASTRUCTURE : 스프링이 내부에서 사용하는 빈
  • ac.getBeansOfType() 을 사용하면 해당 타입의 모든 빈을 조회할 수 있다
    • 부모 타입으로 조회하면, 자식 타입도 함께 조회한다.
    • 모든 자바 객체의 최고 부모인 Object 타입으로 조회하면, 모든 스프링 빈을 조회한다.
BeanFactory와 ApplicationContext

 

BeanFactory

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

ApplicationContext

  • BeanFactory 기능을 모두 상속받아서 제공한다.
  • ApplicationContext는 빈 관리기능 + 편리한 부가 기능을 제공한다.
스프링 빈 설정 메타 정보 - BeanDefinition
  • BeanDefinition 을 빈 설정 메타정보라 한다.
  • @Bean 각각 하나씩 메타 정보가 생성된다.
  • spring container는 이 메타정보를 기반으로 스프링 빈을 생성한다.

 

singleton container

 

스프링 컨테이너는 싱글톤 패턴의 문제점을 해결하면서, 객체 인스턴스를 싱글톤(1개만 생성)으로 관리한다. 지금까지 우리가 학습한 스프링 빈이 바로 싱글톤으로 관리되는 빈이다.

 

@Configuration 을 붙이면 바이트코드를 조작하는 CGLIB 기술을 사용해서 싱글톤을 보장한다. (DI를 사용할때 이미 존재하는 bean의 경우 추가적으로 bean을 생성하지 않고 기존에 생성해놓은 bean을 사용해야 하므로)

 

@Bean
public MemberRepository memberRepository() {
 
    if (memoryMemberRepository가 이미 스프링 컨테이너에 등록되어 있으면?) {
    return 스프링 컨테이너에서 찾아서 반환;
    } else { //스프링 컨테이너에 없으면
    기존 로직을 호출해서 MemoryMemberRepository를 생성하고 스프링 컨테이너에 등록
    return 반환
 }

 

컴포넌트 스캔과 의존관계 자동 주입

스프링은 설정 정보가 없어도 자동으로 스프링 빈을 등록하는 컴포넌트 스캔이라는 기능을 제공한다. 또, 의존관계도 자동으로 주입하는 @Autowired 라는 기능도 제공한다.

의존관계 주입 방법

 

의존관계 주입은 크게 4가지 방법이 있다

  • 생성자 주입 - 불변, 필수 의존관계에 사용(권장)
  • 수정자 주입(setter 주입) - 선택, 변경 가능성이 있는 의존관계에 사용
  • 필드 주입
  • 일반 메서드 주입

생성자가 딱 1개만 있으면 @Autowired를 생략해도 자동 주입 된다. 물론 스프링 빈에만 해당한다 : @Autowired 의 기본 동작은 주입할 대상이 없으면 오류가 발생하는데, 주입할 대상이 없어도 동작하게 하려면 @Autowired(required = false) 로 지정하면 된다

 

Lombok

Lombok의 기능은 model 클래스나 Entity 같은 도메인 클래스 등에 반복되는 getter, setter, toString 등의 메소드를 자동으로 만들어주는 기능을 한다.

롬복 라이브러리가 제공하는 @RequiredArgsConstructor 기능을 사용하면 final이 붙은 필드를 모아서 생 성자를 자동으로 만들어준다.

 

조회 빈이 2개 이상일때

@Autowired 는 타입(Type)으로 조회한다 -> 조회 대상 빈이 2개 이상일 때 해결 방법

  • @Autowired 필드 명 매칭
  • @Qualifier @Qualifier끼리 매칭 빈 이름 매칭
  • @Primary 사용

필드 명 매칭은 먼저 타입 매칭을 시도 하고 그 결과에 여러 빈이 있을 때 추가로 동작하는 기능이다

 

@Autowired 매칭 정리 1. 타입 매칭 2. 타입 매칭의 결과가 2개 이상일 때 필드 명, 파라미터 명으로 빈 이름 매칭

 

필드명을 빈 이름으로 변경

@Autowired private DiscountPolicy discountPolicy ->@Autowired private DiscountPolicy rateDiscountPolicy

 

@Qualifier

빈 등록시 @Qualifier를 붙여 준다

@Component
@Qualifier("mainDiscountPolicy")
public class RateDiscountPolicy implements DiscountPolicy {}

 주입시에 @Qualifier를 붙여주고 등록한 이름을 적어준다.

@Autowired
public OrderServiceImpl(MemberRepository memberRepository, @Qualifier("mainDiscountPolicy") DiscountPolicy discountPolicy) {
    this.memberRepository = memberRepository;
    this.discountPolicy = discountPolicy;
}

 

@Primary

@Primary 는 우선순위를 정하는 방법이다. @Autowired 시에 여러 빈이 매칭되면 @Primary 가 우선권을 가진다.

 

출처

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8

 

[지금 무료] 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술 강의 - 인프런

스프링 입문자가 예제를 만들어가면서 스프링 웹 애플리케이션 개발 전반을 빠르게 학습할 수 있습니다., 스프링 학습 첫 길잡이! 개발 공부의 길을 잃지 않도록 도와드립니다. 📣 확인해주세

www.inflearn.com