본문 바로가기

web +a

스프링 컨테이너 첫 이용

이전에는 AppConfig를 직접 가져와서 DI했지만 이번에는 스프링 기능을 활용할 것이다.

스프링 DI컨테이너가 관리할 수 있도록 AppConfig 파일에 어노테이션을 추가해주자. 

 

 

설정파일이라는 뜻에서 AppConfig에다가 @Configuration을 붙인다.

∨ 여기서 @Bean 메서드가 호출되어 반환된 객체는 스프링 컨테이너에 등록된다. 그러한 객체를 스프링 빈이라고 한다.

스프링 빈 이름 : 메서드 이름

 

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@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(memberRepository(), discountPolicy());
    }
    @Bean
    public DiscountPolicy discountPolicy() {
        return new RateDiscountPolicy();
    }
}

 

① MemberService가 스프링을 이용하도록 변경하자. 

 

스프링 적용 X : AppConfig를 직접 가져왔음

스프링 적용 O : ApplicationContext가 관리한다. 

 

∨ ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

: annotation을 기반으로 한 config라서 이름이 저렇다. 

: ApplicationContext가 스프링 컨테이너다. (참고: 인터페이스임)

∨ applicationContext.getBean("memberService", MemberService. class);

: getBean : 빈 이름으로 객체(스프링 빈)을 가져온다.

: 매개변수 : 스프링빈 이름, 반환타입

 

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();

        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("findMember : " + findMember.getName());

    }
}

 

실행해보면 :

오... 막 singleton 스프링 빈이 생성된다. 

 

 

 

① OrderService도 같은 과정으로 변경하자.

더보기
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class OrderApp {

    public static void main(String[] args) {
//        AppConfig appConfig = new AppConfig();
//        MemberService memberService = appConfig.memberService();
//        OrderService orderService = appConfig.orderService();

        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        MemberService memberService = applicationContext.getBean("memberService", MemberService.class);
        OrderService orderService = applicationContext.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 = " + order);
        System.out.println("order.calculatePrice = " + order.calculatePrice());

    }
}

 

 

이전에 AppConfig를 직접 이용하던 것을

스프링 컨테이너를 통해서 스프링 빈을 찾아쓰는 방식으로 변경한 것이다!

스프링 적용 X :  AppConfig를 직접 가져왔음

스프링 적용 O : ApplicationContext가 관리한다. 

 

 

 

(참고)

스프링 컨테이너는 '스프링 빈 생성'과 '의존관계 주입'의 과정이 분리되어있다. 

우리가 AppConfig에서 작성한 아래의 자바 생성자 코드상에서는 두 과정이 뒤섞여있기는 하지만

더보기
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@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(memberRepository(), discountPolicy());
    }
    @Bean
    public DiscountPolicy discountPolicy() {
        return new RateDiscountPolicy();
    }
}

 

스프링 사이클상 기본적으로 두 단계는 분리되어있다는 것은 알아두자.

 

cf. 단계의 분리 : bean생성 -> @Autowired(의존관계주입)

cf. 수정자(setter)를 사용할 경우 두번째단계에서 의존관계 주입이 일어난다.

cf. 단, 생성자 주입인 경우는 자바코드 특성상 bean생성할 때 의존관계주입이 같이 일어난다.

 


 

? 스프링 컨테이너로 관리하면 좋은점??

엄청 많다고 하는데 이제부터 공부하게된닷

 

다음 학습 : 스프링컨테이너의 핵심기능, 스프링 빈을 더 자세히 알아가는 학습

 

반응형
다른 블로그