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

byeol·2022년 11월 20일
0
post-thumbnail

🙂 김영한님의 스프링 핵심원리를 공부하고 복습할 겸 정리해본다.

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

스프링 컨테이너 생성

✔️ 스프링 컨테이너를 만드는 다양한 설정 형식
스프링 컨테이너는 다양한 형식의 설정 정보를 받아드릴 수 있게 유연하게 설계
1. 자바 설정 클래스로 만들기

  • 스프링 컨테이너 생성
ApplicationCotext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
  • 스프링 컨테이너 생성하기 위한 자바설정 클래스 파일은 앞서 우리가 만들었던 AppConfig.class이다.

2. XML 기반으로 만들기

  • 스프링 컨테이너 생성
 ApplicationContext ac = new GenericXmlApplicationContext("appConfig.xml");
  • 스프링 컨테이너를 생성하기 위한 appConfig.xml파일
<?xml version="1.0" encoding ="UTF-8" ?>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id ="memberService" class = "hello.core.member.MemberServiceImpl">
        <constructor-arg name ="memberRepository" ref="memberRepository"/>
    </bean>

    <bean id = "memberRepository" class="hello.core.member.MemoryMemberRepository"/>

    <bean id="orderService" class="hello.core.order.OrderServiceImpl">
        <constructor-arg name ="memberRepository" ref="memberRepository"/>
        <constructor-arg name ="discountPolicy" ref="discountPolicy"/>
    </bean>

    <bean id="discountPolicy" class="hello.core.discount.RateDiscountPolicy"/>

</beans>

✔️ 스프링 빈 설정 메타 정보 - BeanDefinition
앞서 스프링 컨테이너는 다양한 설정 정보를 받아들이게 유연하게 설계되어 있다고 했다.
이는 BeanDefinition이라는 추상화가 있어 가능

✔️ 스프링 컨테이너 생성

 ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
  • AnnotationConfigApplicationContext는 ApplicationContext의 구현체
  • 컨테이너 생성 과정
    1.ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class); 스프링 컨테이너 생성 ➡️ 2. 스프링 빈 등록 : Configuration이라고 적힌 곳을 설정 클래스 정보로 사용하고 @Bean이 적힌 각 메서드들의 반환 객체를 스프링 컨테이너에 저장한다. 빈 이름은 기본적으로 메서드 이름이고 중복이 허용되지 않으며 @Bean(name="하고픈 이름")으로 수동적으로 이름 부여가 가능하다. ➡️ 3. 스프링 빈 의존 관계 설정: 스프링 컨테이너는 @Bean을 통해 반환된 객체들 사이의 의존관계를 주입한다. 여기서 의존관계를 지정할 수 있다는 것은 정말 객체지향적인 코드가 완성되었다는 것이다.
    사실 이 모든 단계는 한번에 이루어지나 이해를 위해서 개념적으로 나누기

✔️ 스프링 빈의 조회

  • 모든 스프링 빈 조회와 내가 등록한 스프링 빈 조회
    스프링 빈에는 우리가 주입한 것들도 있지만 자동으로 등록된 스프링 빈들도 존재한다.

    ApplicationContext.getBeanDefinitionNames()
    등록된 빈의 이름을 문자열 배열로 받아오기

  • 스프링 빈을 조회할 때 우리는
    ac.getBean("빈이름",타입)
    ac.getBean(타입)
    으로 찾을 수 있다.

  • 동일한 타입이 둘 이상할 때는 NoUniqueBeanDefinitionException이 발생
    그러나 이름을 통해서 조회하거나

MemberRepository memberRepository = ac.getBean("memberRepository1",
MemberRepository.class);

getBeansOfType을 이용하여 Mapd으로 받으면 조회가 가능하다.

Map<String, MemberRepository> beansOfType =
ac.getBeansOfType(MemberRepository.class);
  • 타입 간의 상속관계가 존재한다. 당연한 이야기 그래서 부모 타입으로 조회하면 자식 타입도 함께 조회하여 그 타입의 스프링 빈이 있는지 다 조회한다. 모든 자바의 최고 부모인 object타입으로 조회하면 모든 스프링 빈을 조회한다.
    따라서 해결책
    • 특정 빈 이름 지정
    • 특정 빈 타입 지정
    • 부모이름 타입으로 지정하여 getBeansOfType을 통해 Map으로 받기
    • Object 타입으로 지정하여 getBeansOfType을 통해 Map으로 받기

✔️ BeanFactory와 ApplicationContext

profile
꾸준하게 Ready, Set, Go!

0개의 댓글