@Configuration
public class AppConfig {
@Bean
public DiscountPolicy discountPolicy(){
return new RateDiscountPolicy();
// return new FixDiscountPolicy();
}
@Bean
public MemberRepository memberRepository(){
return new MemoryMemberRepository();
}
@Bean
public MemberService memberService(){
return new MemberServiceImpl(memberRepository());
}
@Bean
public OrderService orderService(){
return new OrderServiceImpl(memberRepository(), discountPolicy());
}
}
{Project root}/src/main/java/resources/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>
xml로 설정정보를 직접 주입한다면 컴파일을 따로 하지 않아도 된다는 장점이 있다.
자바코드로 설정정보를 주입하면 컴파일을 해야한다는 단점이 있지만 주입하기 전에 입맛에 맞게 조작할 수 있으므로 편리하다.
이처럼 직접 주입하지 않고 외부(AppConfig)를 통해 주입하는 방식을 팩토리 메서드라고 한다.
(당연히 AppConfig도 빈에 해당되고 다른 빈은 appConfig를 통해 만들어지므로 팩토리 빈 이라고 한다.)
void xmlAppContext(){
ApplicationContext ac = new GenericXmlApplicationContext("appConfig.xml");
MemberService memberService = ac.getBean("memberService", MemberService.class);
Assertions.assertThat(memberService).isInstanceOf(MemberService.class);
}
자바코드는 AnnotationConfigApplicationContext
으로
XML파일은 GenericXmlApplicationContext
으로
컨텍스트를 가져온다.