[IoC container, 생성자 주입] JAVA > Spring
- WEB/Spring
- 2021. 12. 20. 01:16
AppConifg.java (순수자바로 설정 클래스)
public class AppConfig {
//memberService는 AppConfig를 통해 불러낸다.
//생성자 주입 : 생성자를 통해서 객체를 주입.
public MemberService memberService(){
return new MemberServiceImpl(memberRepository());
}
public MemberRepository memberRepository(){
return new MemoryMemberRepository();
}
public OrderService orderService(){
return new OrderServiceImpl(memberRepository(), discountPolicy());
}
public DiscountPolicy discountPolicy(){
return new FixDiscountPolicy();
}
}
1) AppConfig 자바 클래스에서 설정에 해당하는 부분을 주입한다.
2) MemberRepository를 MemmoryMemberRepository로 주입하는 것을 설정에서 확인 할 수 있다.
3) OrderService를 생성된 memberRepository에서 생성된 MemoryMemberRepository(메모리 레포지토리)로 생성한다.
4) OrderService를 discountPolicy에서 FixDiscountPolicy(정액할인정책)으로 생성한다.
5) memberRepository의 주입을 databaseRepository로 변경하면 손쉽게 레포지토리로 변경이 가능하다.
6) discountPolicy의 주입을 FixDiscountPolicy(정액할인정책) 에서 RateDiscountPolicy(비율할인정책) 로 변경이 가능하다.
MemberServiceImpl.java ( MemberService 인터페이스는 생략 )
MemberServiceImpl.java
public class MemberServiceImpl implements MemberService{
private final MemberRepository memberRepository;
//MemberServiceImpl 이 repository를 선택하도록 하지 않고
//이 부분을 AppConfig에서 설정하도록 한다.
//이렇게 설정하면, 추상화에 대해서만 의존한다. DIP를 만족한다.
//생성자를 통해서 어떤 레포지토리를 선택할 지 정한다.
public MemberServiceImpl(MemberRepository memberRepository){
this.memberRepository = memberRepository;
}
@Override
public void join(Member member) {
memberRepository.save(member);
}
@Override
public Member findMember(Long memberId) {
return memberRepository.findById(memberId);
}
}
1) 멤버에 대한 구현체는 기본적으로 join(회원가입), findMember(회원조회) 의 오버라이드로 구성되어 있으며 해당구현을 위해 memberRepository의 선언이 필요하다.
2) AppConfig가 없었다면, private final MemberRepository memberRepository = new MemoryMemberRepository(); 라는 소스가 들어가야 하지만 AppConfig가 정의됨에 따라 private final MemberRepository memberRepository; 라는 선언과MemberServiceImpl(MemberRepository memberRepository) 생성자를 선택해서 레포지토리를 선택한다.
3) 즉, MemberServiceImpl 클래스에서는 어떤 Repository를 선택할 수 없고, AppConfig.java에서 선택한다.
AppConfig.java (Spring)
Spring, AppConfig.java
@Configuration
public class AppConfig {
//memberService는 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 FixDiscountPolicy();
}
}
1) 순수 자바로 되어있던 AppConfig.java를 spring 형태의 AppConfig.java로 변경한다.
2) IoC Container에 등록하기 위해, @Configuration, @Bean 어노테이션을 이용하여 설정한다.
TEST CODE (Junit5)
public class MemberServiceTest {
MemberService memberService;
@BeforeEach
public void beforeEach(){
//변경 전 (java)
//AppConfig appConfig = new AppConfig();
//memberService = appConfig.memberService();
//Spring 변경 후
ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
memberService = ac.getBean("memberService", MemberService.class);
}
@Test
void join(){
//given
Member member = new Member(1L, "memberA", Grade.VIP);
//when
memberService.join(member);
Member findMember = memberService.findMember(1L);
//then
Assertions.assertThat(member).isEqualTo(findMember);
}
}
1) IoC컨테이너에 AppConfig으로 @Bean형식으로 등록된 서비스들을 불러온다.
2) java 코드에서는 appConfig를 생성하는 코드를 작성했지만,
3) Spring으로 AppConfig.java 설정이 변경된 후에는 AnnoTationConfigApplcationContext에 등록된 bean으로 서비스를 불러 온 후, 코드를 실행한다.
'WEB > Spring' 카테고리의 다른 글
[reactive programming] 백엔드 학습, MSA 이해하기 (0) | 2022.04.19 |
---|---|
RESTful API 문서(#2) SpringBoot, Swagger 적용 (0) | 2022.02.20 |
웹소켓 사용 법 (0) | 2021.02.10 |
[JUnit] Junit 테스트, @RunWith, @ContextConfiguration 그리고 @SpringApplicationConfiguration (0) | 2021.01.21 |
Async 비동기 처리하기 (0) | 2020.12.16 |