[스프링 핵심원리 기본편] 4.3 스프링 설정하기와 BeanDefinition

코린이서현이·2023년 11월 11일
0

👋들어가면서👋

스프링을 설정하는 방법

✔️ 스프링을 설정하는 형식들

📌 애노테이션 기반 자바 코드 설정

new AnnotationConfigApplicationContext(AppConfig.class)
AnnotationConfigApplicationContext 클래스를 사용하면서 자바 코드로된 설정 정보를 넘기면 된다.

📌 XML 설정 사용

  • GenericXmlApplicationContext클래스를 사용하면서 xml 설정 파일을 넘기면 된다.

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="discountPolich" class="hello.core.discount.RateDiscountPolicy"/>
    
    <bean id="oderService" class="hello.core.order.OrderServiceImpl">
        <constructor-arg name="memberRepository" ref="memberRepository"/>
        <constructor-arg name="discountPolicy" ref="discountPolich"/>
    </bean>
</beans>

🤔 xml의 name은..?

  • Xml파일이 스프링 빈을 등록하면서 생성자 매개변수를 등록하는 데 사용된다.
  • 따라서 생성자 변수 순서가 다르더라도 name만 같다면 정상 등록된다.

⚠️ 생성자의 매개변수와 이름이 다를 경우에는..?

org.springframework.beans.factory.UnsatisfiedDependencyException: 
Error creating bean with name 'oderService' defined in class path resource [appConfig.xml]: 
Unsatisfied dependency expressed through constructor parameter 0: 
Ambiguous argument values for parameter of type 
[hello.core.member.MemberRepository] - did you specify the correct bean references as arguments?
org.springframework.beans.factory.UnsatisfiedDependencyException: 
클래스 경로 리소스 [appConfig.xml]에 정의된 이름이 'oderService'인 Bean을 생성하는 중 오류가 발생했습니다. 
생성자 매개변수를 통해 표현된 충족되지 않은 종속성 0: [hello.core.member 유형의 매개변수에 대한 모호한 인수 값 .MemberRepository] 
- 올바른 Bean 참조를 인수로 지정했습니까?

📄 XmlAppConfig 사용 자바 코드

public class XmlApplication {

  @Test
  void xmlAppContext() {
    ApplicationContext ac = new GenericXmlApplicationContext("appConfig.xml");

    MemberService memberService = ac.getBean("memberService", MemberService.class);
    assertThat(memberService).isInstanceOf(MemberServiceImpl.class);

  }
}

👉 정상 작동

📌 BeanDefinition

메타정보를 만드는 2가지 방법이 있다.

  1. 자바 코드를 읽어서 BeanDefinition
  2. xml을 읽어서 BeanDefinition

➡️ 스프링 컨테이너는 이 메타 정보를 기반으로 빈을 생성한다.
역할과 구현을 개념적으로 나눈 것이다.

✍️ BeanDefinition을 만드는 상세 과정

✔️ BeanDefinitiond을 만드는 Reader

✔️ 스프링은 다양한 형태의 설정 정보를 모두 BeanDefinition으로 추상화해서 사용한다.

"빈 설정 메타정보 확인"

public class BeanDefinitionTset {

  AnnotationConfigApplicationContext ac =  new AnnotationConfigApplicationContext(AppConfig.class);


    /*
      BeanClassName: 생성할 빈의 클래스 명(자바 설정 처럼 팩토리 역할의 빈을 사용하면 없음)
      factoryBeanName: 팩토리 역할의 빈을 사용할 경우 이름, 예) appConfig
      factoryMethodName: 빈을 생성할 팩토리 메서드 지정, 예) memberService
      Scope: 싱글톤(기본값)
      lazyInit: 스프링 컨테이너를 생성할 때 빈을 생성하는 것이 아니라, 실제 빈을 사용할 때 까지 최대한 생성을 지연
      처리 하는지 여부
      InitMethodName: 빈을 생성하고, 의존관계를 적용한 뒤에 호출되는 초기화 메서드 명
      DestroyMethodName: 빈의 생명주기가 끝나서 제거하기 직전에 호출되는 메서드 명
      Constructor arguments, Properties: 의존관계 주입에서 사용한다. (자바 설정 처럼 팩토리 역할의 빈을 사용하면 없음)
   */
  @Test
  @DisplayName("빈 설정 메타 정보 확인")
  void findApplicationBean() {
    String[] beanDefinitionNames = ac.getBeanDefinitionNames();
    for (String beanDefinitionName : beanDefinitionNames) {
      BeanDefinition beanDefinition = ac.getBeanDefinition(beanDefinitionName);
      if (beanDefinition.getRole() == BeanDefinition.ROLE_APPLICATION) {
        System.out.println("beanDefinitionName+ = " + beanDefinitionName +
                " beanDefinition = " + beanDefinition);
      }
    }
  }

}

👉 실행화면

beanDefinitionName+ = appConfig beanDefinition = Generic bean: 
class [hello.core.AppConfig$$EnhancerBySpringCGLIB$$7fe25ae1]; scope=singleton; 
abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=true; 
primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; 
destroyMethodName=null

👋마무리하면서👋

화이팅
profile
24년도까지 프로젝트 두개를 마치고 25년에는 개발 팀장을 할 수 있는 실력이 되자!

0개의 댓글