- BeanFactory 와  ApplicationContext 를 스프링 컨테이너라고 한다. 

- BeanFactory 기능을 상속받은 ApplicationContext ( ApplicationContext 는 BeanFactory의 부가기능을 더한 것)

그 밑에는 AnnotationConfig ApplicationContext 구현클래스

 

BeanFactory 
  • 스프링 컨테이너의 최상위 인터페이스
  • 스프링 빈을 관리하고 조회하는 역할을 담당한다
  • getBean() 을 제공
  • 지금까지 우리가 사용했던 대부분의 기능이  BeanFactory가 제공하는 기능이다. 
  • 사실 직접 BeanFactory 를 사용할 일은 거의 없다. 부가기능을 포함 된 ApplicationContext 을 사용한다.

 

ApplicationContext 
  • BeanFactory 기능을 모두 상속받아서 제공
  • BeanFactory 와 ApplicationContext의 차이는?
    • 애플리케이션을 개발할때는 빈은 관리하고 조회하는 기능( BeanFactory )은 물론이고 수많은 부가기능은 ApplicationContext 가 갖고있다.

 

ApplicationContext 부가기능

 

1. 메세지 소스를 활용한 국제화 기능

 : 예를들어 한국에는 한국어로, 영어권으로 가면 영어로 출력

 

2. 환경변수

  : 로컬, 개발, 운영 등을 구분해서 처리

 

3. 애플리케이션 이벤트

  : 이벤트 발행하고 구독하는 모델을 편리하게 지원

 

2. 편리한 리소스 조회

  : 파일, 클래스패스 , 외부 등에서 리소스르 편리하게 조회

 

 

 

 


 

 

스프링은 다양한 설정 형식

 

 

 

 

스프링은 다양한 설정 형식 지원을 한다 > 자바코드, XML , Groovy 등등

 

 

 

어노테이션 기반 자바 코드 설정 사용

 

AnnotationConfigApplicationContext 클래스를 사용하여 자바 코드로 된 설정 정보를 넘긴다. 

new AnnotationConfigApplicationContext(AppConfig.class);

 

 

 

 

XML 설정 사용

 

최근에는 스프링 부트를 많이 사용하면서 XML 기반 설정은 잘 사용하지 않는다.

장점으로는 컴파일 없이 빈 설정 정보를 변경할 수 있다

 

 

 

1. 테스트용 스프링 컨테이너 생성하기

[XmlAppContext 클래스]

public class XmlAppContext {

	@Test
	void xmlAppContext() {
		ApplicationContext ac = new GenericXmlApplicationContext("appConfig.xml");
		MemberService memberService = ac.getBean("memberService", MemberService.class);
		Assertions.assertThat(memberService).isInstanceOf(MemberService.class);
	}
}

 

GenericXmlApplicationContext 만 바뀌었을뿐 나머지는 ApplicationContext  코드와 같다

 

 

 

2. xml 생성하기

 

resource 폴더안에  appConfig.xml 생성하기

 

 

 

[ 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"></constructor-arg>
	</bean>
	
	<!--id="memberRepository"가 위의 refer="memberRepository"로 넘어가며 구현객체는 hello.core.member.MemoryMemberRepository-->
	<bean id="memberRepository" class="hello.core.member.MemoryMemberRepository"/>
	
	<bean id="orderService" class="hello.core.order.OrderServiceImpl">
		<constructor-arg name="memberRepository" ref="memberRepository"></constructor-arg>
		<constructor-arg name="discountPolicy" ref="discountPolicy"></constructor-arg>
	</bean>
	
	<bean id="discountPolicy" class="hello.core.discount.RateDiscountPolicy"></bean>

</beans>

 

 

 

아래는 원래 자바코드로 설정한 [ AppConfig.java ] 

@Configuration
public class AppConfig {

	@Bean
	public MemberService memberService() {
		return new MemberServiceImpl(memberRepository());
	}
	
	@Bean
	public MemoryMemberRepository memberRepository() {
		return new MemoryMemberRepository();
	}
    
	@Bean
	public OrderService orderService() {
		return new OrderServiceImpl(memberRepository(), discountPolicy()); //discountPolicy()로 대체해주기
	}
	
	@Bean
	public DiscountPolicy discountPolicy() {
//		return new FixDiscountPolicy();  // 1만원이든 2만원이든 천원 할인적용
		return new RateDiscountPolicy(); // 1만원 천원할인, 2만원이면 2천원할인
	}
	
}

 

 

 

 

AppConfig.java 자바코드와 appConfig.xml 기반의 스프링 설정 정보를 비교해보자

 

[AppConfig.java] 

@Bean
public MemberService memberService() {
    return new MemberServiceImpl(memberRepository());
}

 

 [appConfig.xml]

<bean id="memberService" class="hello.core.member.MemberServiceImpl">
    <constructor-arg name="memberRepository" ref="memberRepository"></constructor-arg>
</bean>
  • <bean id="memberService" class="hello.core.member.MemberServiceImpl">
    • 빈 이름 memberService , 구현 클래스 MemberServiceImpl (패키지 이름까지 모두 적기)
  • <constructor-arg name="memberRepository" ref="memberRepository"></constructor-arg>
    • 생성자 이름 memberRepository , 참조(ref) 를 넣어줘야하는데 없으니 만들자 

 

 

[AppConfig.java] 

@Bean
public MemoryMemberRepository memberRepository() {
    return new MemoryMemberRepository();
}

 

 [appConfig.xml]

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

 

 

 

 

[테스트 결과] 빈으로 등록된 메서드 이름이 나옴 

 

 

 

 

 

 

 

스프링은 이렇게 java와 xml 처럼 다양한 설정 형식을 지원한다 

어떻게 가능한가? 

  • BeanDefinition 이라는 추상화가 있다
    • XML 또는 자바코드를 읽어서 BeanDefinition 을 만든다 
    • 스프링 컨테이너는 BeanDefinition 만 알면  XML 인지 자바코드인지 몰라도 된다 
    • 역할과 구현을 나눈 것 처럼!
  • BeanDefinition 을 비 설정 메타 정보라고 하는데 
    • @Bean, <bean> 을 쓰면 각 하나씩 메타 정보가 생성된다.
  • 스프링 컨테이너는 메타정보를 기반으로 스프링 빈을 생성한다. 

 

 

 

 

반응형
LIST

+ Recent posts