Blog

[SpringCore] 스프링 컨테이너와 스프링 빈 - 스프링 컨테이너의 설정 형식 지원 (Java 어노테이션/XML)과 BeanDefinition

Category
Author
Tags
PinOnMain
1 more property
스프링 컨테이너는 다양한 형식의 설정 정보를 받아드릴 수 있게 설계되어 있다.
Table of Content

자바 코드 설정 사용 방식

현재까지 사용했던 new AnnotationConfigApplicationContext(AppConfig.class); 처럼 해당 클래스를 통해 자바 코드로 된 설정 정보를 넘기는 방법
@Configuration public class AppConfig { @Bean public MemberService memberService() { return new MemberServiceImpl(memberRepository()); } @Bean public MemberRepository memberRepository() { return new MemoryMemberRepository(); } @Bean public OrderService orderService() { return new OrderServiceImpl(memberRepository(), discountPolicy()); } @Bean public DiscountPolicy discountPolicy() { return new RateDiscountPolicy(); } }
Java
복사
public class MemberApp { public static void main(String[] args) { ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class); ... }
Java
복사

XML 설정 사용 방식

위 AppConfig.java를 대신하여 appConfig.xml 소스코드를 설정 정보로 인식하게 하는 방법이다. 문법은 상이하나 거의 비슷한 구조를 가지고 있다. <bean> 과 같은 태그로 변경되고 속성으로 관리하는 문법이 사용된다.
<?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>
XML
복사
XML 설정 파일을 로드하여 사용하기 위해서는 ApplicationContext의 구현체를 GenericXmlApplicationContext를 사용해야 한다. 또한 xml의 경로는 main/resources/appConfig.xml 처럼 위치하는 것을 기본 컨텍스트 경로로 한다.
package hello.core.xml; import hello.core.member.MemberService; import org.junit.jupiter.api.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.GenericXmlApplicationContext; import static org.assertj.core.api.Assertions.assertThat; public class XmlAppContextTest { @Test void xmlAppContext() { ApplicationContext ac = new GenericXmlApplicationContext("appConfig.xml"); MemberService memberService = ac.getBean("memberService", MemberService.class); assertThat(memberService).isInstanceOf(MemberService.class); } }
Java
복사
XML 방식은 최근 권장되지 않는것 처럼 보이는데 레거시 프로젝트에서 자주 보일 수 있으며 현재도 사용 될 수 있기 때문에 대치하는 방법을 알아둬야 할 것 같다.

스프링 빈 설정 메타 정보 - BeanDefinition

위 처럼 스프링 컨테이너는 설정 형식을 어떻게 지원 하는 것인가?
스프링 컨테이너가 BeanDefinition이라는 추상화 인터페이스를 의존하고 있기 때문이다. (OCP 확장오픈 수정폐쇄가 적용되어 있기 때문) 따라서 BeanDefinition 추상화의 실 구현 객체 변경에 따라 유연하게 설정 파일을 선택하게 되는 것이다.
각 스프링 컨테이너 구현체(ex:AnnotationConfigApplicationContext)는 각자의 리더(Reader)를 통해 정보를 읽어 BeanDefinition을 생성하게 된다.
이는 할인 정책만 의존하고 있는 주문 서비스가 할인 정책만 알고 있어도 되는 상황과 유사하다. 스프링 컨테이너는 BeanDefinition빈 메타 정보만 알고 있어도 되는 것 같다.
예로 AppConfig.class를 통해 자바 코드를 설정 정보로 사용한 경우 BeanDefinition 메타 정보를 조회하는 테스트 코드이다.
package hello.core.beandefinition; import hello.core.AppConfig; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class BeanDefinitionTest { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class); @Test @DisplayName("빈 설정 메타정보 확인") void findApplicationBeanMetaInfo() { 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); } } } }
Java
복사
조회를 통해 BeanDefinition 메타 정보인 빈 클래스 이름, 팩토리 빈 이름, 전역범위인 스코프, Lazy 처리 여부 등 정보를 확인 할 수 있다.
Search
 | Main Page | Category |  Tags | About Me | Contact | Portfolio