Spring에 발 들이기 3

바람찬허파·2023년 9월 3일
0

IOC, DI

IOC 제어의 역전
제어권의 완전히 넘어가는 것
예를 들어 AppConfig에서 어떤 객체를 넣을 지 결정함.

DI
의존관계 주입을 사용하면, 정적인 클래스 의존관계는 전혀 건들이지 않고도,
동적인 객체 인스턴스 의존관계를 변경할 수 있다.

Spring 도입하기

기존에는 JAVA 로만 이루어졌지만, 이번에는 Spring을 코드에 도입하고자 한다.

1. AppConfig 수정

@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"로 조회

스프링 컨테이너에 객체를 스프링 빈으로 등록 & 스프링 빈을 컨테이너에서 찾아서 사용

0개의 댓글