AppConfig 스프링 기반으로 변경
// AppConfig는 애플리케이션의 실제 동작에 필요한 "구현 객체를 생성"한다.
// AppConfig는 MemoryMemberRepository객체를 생성하고 그 참조값 MemberServiceImpl을 생성하면서 생성자로 전달한다.
// 클라이언트인 MemberServiceImpl입장에서 보면 의존관계를 마치 외부에서 주입해주는 것 같다고 해서 DI(Dependency Injection) = 의존관계 주입 또는 의존성 주입이라고 한다.
@Configuration : AppConfig에 설정을 구성
@Bean : 각 메서드에 사용. 스프링 컨테이너에 스프링 빈으로 등록
🟢🟡🟠 주의
- 빈 이름은 메서드의 이름을 사용하지만, 빈 이름을 직접 부여할 수도 있다.(@Bean(name="memberService2")
- 빈 이름은 항상 다른 이름을 부여. 같은 이름을 부여하면 다른 빈이 무시되거나, 덮어버릴 수 있다.
@Configuration
public class AppConfig {
// AppConfig는 애플리케이션의 실제 동작에 필요한 "구현 객체를 생성"한다.
// AppConfig는 MemoryMemberRepository객체를 생성하고 그 참조값 MemberServiceImpl을 생성하면서 생성자로 전달한다.
// 클라이언트인 MemberServiceImpl입장에서 보면 의존관계를 마치 외부에서 주입해주는 것 같다고 해서 DI(Dependency Injection) = 의존관계 주입 또는 의존성 주입이라고 한다.
@Bean
public MemberService memberService() {
// AppConfig는 생선한 객체 인스턴스의 참조(레퍼런스)를 "생성자를 통해서 주입(연결)"한다.
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();
// 할인정책이 바뀔 경우, AppConfig의 여기만 고치면 됨..
// return new RateDiscountPolicy();
}
}
MemberApp에 스프링 컨테이너 적용
스프링 컨테이너 적용 전
기존에는 AppConfig를 사용해서 직접 객체를 생성하고 DI(Dependency Injection, 의존성 주입) 했다.
AppConfig appConfig = new AppConfig();
MemberService memberService = appConfig.memberService();
스프링 컨테이너 적용 후
ApplicationContext = 스프링 컨테이너
스프링 컨테이너는 @Configuration이 붙은 AppConfig를 설정(구성) 정보로 사용한다.
@Bean이 적힌 메서드를 호출해서 반환된 객체를 스프링 컨테이너에 등록한다. 이렇게 스프링 컨테이너에 등록된 객체를 스프링 빈이라고 한다.
스프링 빈은 @Bean이 붙은 메서드의 명을 스프링 빈의 이름으로 사용한다.(memberService, orderService)
이전에는 필요한 객체를 AppConfig를 사용해서 직접 사용해서 조회했지만,
이제는 applicationContext.getBean()메서드를 사용해서 찾을 수 있다.
AppConfig에 있는 환경 설정 정보를 가지고 스프링이 생성한 객체를 Spring 컨테이너에다 다 넣어서 관리한다.
📌 ApplicationContext = 스프링 컨테이너
📌 applicationContext.getBean() : ApplicationContext에 등록된 Bean(=메서드)찾기
// ApplicationContext = 스프링 컨테이너
// 스프링 컨테이너에 등록
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
// AppConfig의 "memberService"메소드를 찾을건데, 타입은 MemberService.class임
// (AppConfig에서 사용한 "메소드 이름", type)
MemberService memberService = applicationContext.getBean("memberService", MemberService.class);
public class MemberApp {
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
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());
}
}
여기서 드는 의문점.. Spring Container를 사용한 후가 코드가 더 긴데 좋은게 맞나?
추후 게시글에서 풀이하겠다..
'공부 > Spring' 카테고리의 다른 글
[Spring] 스프링 빈 조회 - 동일한 타입이 둘 이상일 때 (0) | 2023.11.07 |
---|---|
[Spring] 스프링 빈 조회 - 기본 (0) | 2023.11.06 |
[Spring] IoC, DI, 컨테이너 (2) | 2023.10.04 |
[Spring] SOLID원칙(코드 예시) (0) | 2023.09.27 |
[Spring] @Controller와 @RestController의 차이 (0) | 2023.09.03 |