IOC 제어의 역전
제어권의 완전히 넘어가는 것
예를 들어 AppConfig에서 어떤 객체를 넣을 지 결정함.
DI
의존관계 주입을 사용하면, 정적인 클래스 의존관계는 전혀 건들이지 않고도,
동적인 객체 인스턴스 의존관계를 변경할 수 있다.
기존에는 JAVA 로만 이루어졌지만, 이번에는 Spring을 코드에 도입하고자 한다.
@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(discountPolicy(), memberRepository());
}
@Bean
public DiscountPolicy discountPolicy() {
return new RateDiscountPolicy();
}
}
//기존 코드
public class OrderApp {
public static void main(String[] args) {
AppConfig appConfig = new AppConfig();
MemberService memberService = appConfig.memberService();
OrderService orderService = appConfig.orderService();
Long memberId = 1L;
Member member = new Member(1L, "memberA", Grade.VIP);
memberService.join(member);
memberService.join(new Member(2L, "memberB", Grade.BASIC));
Order orderA = orderService.createOrder(1L, "toothpaste", 2000);
Order orderB = orderService.createOrder(2L, "milk", 10000);
System.out.println("orderA = " + orderA);
System.out.println("orderB = " + orderB);
}
}
public class OrderApp {
public static void main(String[] args) {
// AppConfig appConfig = new AppConfig();
// MemberService memberService = appConfig.memberService();
// OrderService orderService = appConfig.orderService();
ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
MemberService memberService = ac.getBean("memberService", MemberService.class);
OrderService orderService = ac.getBean("orderService", OrderService.class);
Long memberId = 1L;
Member member = new Member(1L, "memberA", Grade.VIP);
memberService.join(member);
memberService.join(new Member(2L, "memberB", Grade.BASIC));
Order orderA = orderService.createOrder(1L, "toothpaste", 2000);
Order orderB = orderService.createOrder(2L, "milk", 10000);
System.out.println("orderA = " + orderA);
System.out.println("orderB = " + orderB);
}
}
이전에는 AppConfig 객체를 생성한 뒤, 객체의 필드에서 memberService, orderService의 생성자를 호출 -> 객체를 생성하였다.
현재는 @Bean 어노테이션이 붙은 메서드의 리턴값 -> 모두 스프링 빈으로 스프링 컨테이너에 등록 -> getBean으로 컨테이너에 등록된 객체 (스프링 빈) 호출
ApplicationContext가 스프링 컨테이너
기존에는 AppConfig를 사용해 객체 생성, DI <-> 스프링 컨테이너를 통해 사용
@Configuration이 붙은 AppConfig를 설정정보로 사용 -> @Bean 이라 적힌 메서드의 호출해서 리턴된 객체를 스프링컨테이너에 등록 => 스프링 빈
@Bean이 붙은 메서드의 명 -> 스프링 빈의 이름이 됨
// AppConfig
@Configuration
public class AppConfig {
@Bean
public MemberService memberService(){
return new MemberServiceImpl(memberRepository());
}
//...
// OrderApp
ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
MemberService memberService = ac.getBean("memberService", MemberService.class);
// AppConfig의 메소드 이름인 "memberService"로 조회
스프링 컨테이너에 객체를 스프링 빈으로 등록 & 스프링 빈을 컨테이너에서 찾아서 사용