지금까지 순수한 자바 코드만으로 DI를 적용했습니다.
이제 스프링을 사용해봅시다.
package hello.core;
import hello.core.discount.DiscountPolicy;
import hello.core.discount.RateDiscountPolicy;
import hello.core.member.MemberRepository;
import hello.core.member.MemberService;
import hello.core.member.MemberServiceImpl;
import hello.core.member.MemoryMemberRepository;
import hello.core.order.OrderService;
import hello.core.order.OrderServiceImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration //...1
public class AppConfig {
@Bean //...2
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();
}
}
@Configuration
항상 import를 조심해야 합니다.
이게 한마디로 설정 정보라는 뜻 입니다. 애플리케이션의 구성을 담당하는 설정 정보라고 보면 됩니다.
스프링에서는 설정 정보에 @Configuration를 적어주게 되어 있습니다.
@Configuration 은 설정정보가 있는 여러개의 클래스에 모두 붙을 수 있는데, 그게 여러개의 설정정보가 되는거고, 하나의 스프링 컨테이너에 여러개의 설정정보가 들어가는 겁니다.
즉, 스프링 컨테이너는 하나이고, @Configuration은 설정정보인데, 설정정보는 여러개가 될 수 있습니다.
@Bean
이제 스프링을 쓰도록 해봅시다.
MemberApp을 AppConfig버전에서 스프링을 사용하는 버전으로 바꿔봅시다.
package hello.core;
import hello.core.member.Grade;
import hello.core.member.Member;
import hello.core.member.MemberService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MemberApp {
public static void main(String[] args) {
// AppConfig appConfig = new AppConfig();
// MemberService memberService = appConfig.memberService();
//...1
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
//...2
MemberService memberService = applicationContext.getBean("memberService", MemberService.class);
Member member = new Member(1L, "memberA", Grade.VIP);
memberService.join(member);
Member findMember = memberService.findMember(1L);
System.out.println("new member = " + member.getName());
System.out.println("find Member = " + findMember.getName());
}
}
잠시 주석처리를 해줍시다
스프링 생성
스프링은 모든게 ApplicationContext에서 시작합니다. 이게 스프링 컨테이너라고 보면 됩니다.
@Bean 객체들을 다 관리해줍니다.
그리고 생성을 할 때는 AnnotationConfigApplicationContext();
를 적어줘야합니다.
그리고 안에 파라미터로 AppConfig.class를 넣어주면 됩니다.
<aside> ❗ 자바언어에서 클래스의 인스턴스가 아니라 타입 자체를 넘길 때는 AppConfig라고 하면 안되고, AppConfig.class라고 해주어야 합니다.
</aside>
이렇게 하면 AppConfig에 있는 환경 설정 정보를 가지고 스프링이 @Bean 붙은 것들을 스프링 컨테이너에 객체 생성한 것들을 다 넣어서 관리해 줍니다.
기존에 찾아올 때는 주석처리한 것 처럼 직접 찾아왔습니다. 이제는 스프링 컨테이너를 통해서 찾아옵니다.
getBean해서 이름과 타입을 적습니다.
AppConfig에서 memberService를 꺼낼 것 입니다. 이 때 기본적으로 메서드 이름으로 등록이 됩니다.
그래서 getBean의 이름에 memberService를 적어줍니다. (memberService객체를 찾을거야)
타입을 적어줘야 반환 타입이 딱 맞습니다.
즉, 이름은 memberService이고 타입은 MemberService라는 것 입니다.