Spring/Spring core basic

[Spring core basic] 16 - 스프링으로 전환하기

Kloong 2022. 5. 2. 01:16

참고

더보기

Spring core basic 시리즈는 김영한 님의 "스프링 핵심 원리 - 기본편" 강의를 정리한 글입니다. 글에 첨부된 사진은 해당 강의의 강의 자료에서 캡쳐한 것입니다. 제 Github에만 올려뒀다가, 정보 공유와 강의 홍보(?)를 위해 블로그에도 업로드합니다. 마크다운을 잘 쓰지 못해서 가독성이 조금 떨어지는 점 양해 바랍니다.

 

 

스프링 핵심 원리 - 기본편 - 인프런 | 강의

스프링 입문자가 예제를 만들어가면서 스프링의 핵심 원리를 이해하고, 스프링 기본기를 확실히 다질 수 있습니다., - 강의 소개 | 인프런...

www.inflearn.com

스프링으로 전환하기

지금까지 순수한 자바 코드만으로 DI를 적용했다. 이제 스프링을 사용해보자.

Spring framework 적용

AppConfig.java

package com.kloong.corebasic1;

//import 생략

//Spring에게 이 클래스가 application의 구성 정보를 담당하는 클래스라는 것을 알려줌
@Configuration
public class AppConfig {

    @Bean
    public MemberRepository memberRepository() {
        return new MemoryMemberRepository();
    }

    @Bean
    public DiscountPolicy discountPolicy() {
        return new RateDiscountPolicy();
    }

    @Bean
    public MemberService memberService() {
        return new MemberServiceImpl(memberRepository());
    }

    @Bean
    public OrderService orderService() {
        return new OrderServiceImpl(memberRepository(), discountPolicy());
    }

}

AppConfig가 애플리케이션을 설정하는 클래스라는 것을 Spring에게 알려주기 위해 @Configuration 을 붙여준다.

그리고 각 메서드에 @Bean 을 붙여준다. 이렇게 하면 Spring이 각 객체를 Spring bean으로 등록하여 관리한다.

MemberApp.java

package com.kloong.corebasic1;

//import 생략

public class MemberApp {
    public static void main(String[] args) {

//        AppConfig appConfig = new AppConfig();
//        MemberService memberService = appConfig.memberService();

        //AppConfig의 구성 정보를 보고 Spring이 bean을 등록해서 관리해준다.
        ApplicationContext applicationContext =
                new AnnotationConfigApplicationContext(AppConfig.class);

        //Spring bean은 기본적으로 메소드 이름으로 등록된다. name 파라미터에 메소드 이름을 넣어준다.
        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());
    }
}

OrderApp.java

package com.kloong.corebasic1;

//import 생략

public class OrderApp {
    public static void main(String[] args) {
        AppConfig appConfig = new AppConfig();

        //return new MemberServiceImpl(new MemoryMemberRepository());
        //MemberService memberService = appConfig.memberService();
        //return new OrderServiceImpl(new MemoryMemberRepository(), new FixDiscountPolicy());
        //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(memberId, "memberA", Grade.VIP);
        memberService.join(member);

        Order order = orderService.createOrder(memberId, "itemA", 10000);

        System.out.println(order);
    }
}

MemberApp과 OrderApp을 실행시키면, Spring 관련 로그가 몇 줄 뜨는 것을 제외하고는 기존과 동일한 결과가 출력된다.

Spring Container

MemberApp.java와 OrderApp.java의 ApplicationContext 를 스프링 컨테이너라고 한다.

기존에는 개발자가 AppConfig를 사용해서 직접 객체를 생성했지만, 이제부터는 스프링 컨테이너를 사용해서 이 작업을 해주면 된다.

스프링 컨테이너는 @Configuration 이 붙은 AppConfig를 설정(구성) 정보로 사용한다. AppConfig 클래스에서 @Bean 이라 적힌 메서드를 모두 호출해서 반환된 객체를 스프링 컨테이너에 등록한다. 이렇게 스프링 컨테이너에 등록된 객체를 Spring bean이라 한다.

스프링 빈은 @Bean 이 붙은 메서드의 명을 스프링 빈의 이름으로 사용한다. (Ex. memberService,
orderService). 물론 이름을 바꿀 수 있지만, 일반적으로 이름을 바꾸는 경우는 거의 없다.

이전에는 개발자가 필요한 객체를 AppConfig 를 사용해서 직접 생성하고 조회했지만, 이제부터는 스프링 컨테이너를 통해서 필요한 스프링 빈(객체)를 찾아야 한다. 스프링 빈은 applicationContext.getBean() 메서드를 사용해서 찾을 수 있다.

기존에는 개발자가 직접 Java 코드로 모든 것을 했다면, 이제부터는 스프링 컨테이너에 객체를 스프링 빈으로 등록하고, 스프링 컨테이너에서 스프링 빈을 찾아서 사용하도록 변경되었다.

Spring Container의 필요성...?

DI container의 역할을 하는 AppConfig로 DIP와 SCP를 만족시키는 프로그램을 개발할 수 있었다.

그런데 Spring Container를 적용했더니 객체 생성 및 관리를 Spring이 알아서 해준다고 한다.

그런데 그거 말고는 아직까지는 달라지는 게 없어 보인다. 오히려 코드가 더 복잡해진 것 같다. Spring container의 장점이 뭘까? 이제부터 그 것을 알아볼 것이다.