본문 바로가기

SPRING/Spring

[스프링| 스프링 핵심 원리 | 기본편 | 스프링 핵심 원리 이해2 - 객체 지향 원리 적용]스프링으로 전환하기

@Configuration
// 이 클래스가 스프링의 설정 정보를 담고 있는 클래스임을 선언한다. 스프링 컨테이너는 이 클래스를 설정 정보로 사용한다.

public class AppConfig {

    @Bean
    public MemberService memberService() {
        return new MemberServiceImpl(memberRepository());
    }
    // MemberService 타입의 빈을 생성하고, 이 빈은 MemberRepository를 의존성으로 주입받는다.

    @Bean
    public MemberRepository memberRepository() {
        return new MemoryMemberRepository();
    }
    // MemberRepository 타입의 빈을 생성한다. 구현체로는 MemoryMemberRepository를 사용한다.

    @Bean
    public OrderService orderService() {
        return new OrderServiceImpl(memberRepository(), discountPolicy());
    }
    // OrderService 타입의 빈을 생성하고, 이 빈은 MemberRepository와 DiscountPolicy를 의존성으로 주입받는다.

    @Bean
    public DiscountPolicy discountPolicy() {
        return new RateDiscountPolicy();
    }
    // DiscountPolicy 타입의 빈을 생성한다. 구현체로는 RateDiscountPolicy를 사용한다.
}

@Configuration 어노테이션 설명

@Configuration은 해당 클래스가 스프링의 설정 정보를 담고 있는 클래스임을 명시하며, 스프링 컨테이너가 이 클래스를 구성 정보로 사용하여 빈(Bean)들을 등록하고 관리하는 데 사용된다. 이 어노테이션이 붙은 클래스 내부에서 정의된 메서드들은 특정한 빈을 생성하고 초기화하는 데 필요한 메타데이터를 제공한다.

@Bean 어노테이션 설명

@Bean 어노테이션은 메서드가 스프링 컨테이너에 의해 관리되는 빈 객체를 생성한다는 것을 명시한다. @Bean 어노테이션이 붙은 메서드의 이름은 스프링 컨테이너에 등록되는 빈의 이름으로 사용되며, 메서드가 반환하는 객체가 빈 객체로 등록된다. 이 객체들은 스프링 컨테이너에 의해 싱글톤으로 관리되거나, 요청에 따라 새로운 인스턴스가 생성되어 제공될 수 있다.

 

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

        //AppConfig appConfig = new AppConfig();
        //MemberService memberService = appConfig.memberService();
        // 위 두 줄은 수동으로 AppConfig 클래스를 사용하여 의존성 주입을 설정하는 코드의 예시다. 현재는 주석 처리되어 있음.

        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        // 스프링 컨텍스트를 초기화하고 AppConfig 클래스를 설정 정보로 사용하여 빈을 관리한다.

        MemberService memberService = applicationContext.getBean("memberService", MemberService.class);
        // ApplicationContext를 통해 "memberService"라는 이름의 빈을 가져온다. 이 빈은 MemberService 타입이다.

        Member member = new Member(1L, "member1", Grade.VIP);
        // 새로운 Member 객체를 생성한다. ID는 1L, 이름은 "member1", 등급은 VIP다.

        memberService.join(member);
        // memberService를 사용하여 생성한 member 객체를 회원으로 등록한다.

        Member findMember = memberService.findMember(1L);
        // memberService를 사용하여 ID가 1L인 회원을 찾는다.

        System.out.println("new member = " + member.getName());
        // 콘솔에 새로 등록된 회원의 이름을 출력한다.

        System.out.println("find Member = " + findMember.getName());
        // 콘솔에 찾은 회원의 이름을 출력한다.
    }
}
public class MemberApp {
    public static void main(String[] args) {

        //AppConfig appConfig = new AppConfig();
        //MemberService memberService = appConfig.memberService();
        // 위 두 줄은 수동으로 AppConfig 클래스를 사용하여 의존성 주입을 설정하는 코드의 예시다. 현재는 주석 처리되어 있음.

        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        // 스프링 컨텍스트를 초기화하고 AppConfig 클래스를 설정 정보로 사용하여 빈을 관리한다.

        MemberService memberService = applicationContext.getBean("memberService", MemberService.class);
        // ApplicationContext를 통해 "memberService"라는 이름의 빈을 가져온다. 이 빈은 MemberService 타입이다.

        Member member = new Member(1L, "member1", Grade.VIP);
        // 새로운 Member 객체를 생성한다. ID는 1L, 이름은 "member1", 등급은 VIP다.

        memberService.join(member);
        // memberService를 사용하여 생성한 member 객체를 회원으로 등록한다.

        Member findMember = memberService.findMember(1L);
        // memberService를 사용하여 ID가 1L인 회원을 찾는다.

        System.out.println("new member = " + member.getName());
        // 콘솔에 새로 등록된 회원의 이름을 출력한다.

        System.out.println("find Member = " + findMember.getName());
        // 콘솔에 찾은 회원의 이름을 출력한다.
    }
}
  1. ApplicationContext: 이는 스프링의 DI 컨테이너로, 애플리케이션에 등록된 모든 빈의 생성, 관리, 의존성 주입을 담당한다. ApplicationContext는 다양한 종류의 빈 설정과 라이프사이클 관리 기능을 제공하여, 객체들 간의 결합도를 낮추고 유연성을 높이는 데 중요한 역할을 한다.
  2. AnnotationConfigApplicationContext: 이 클래스는 Java의 어노테이션 기반의 구성 클래스를 사용하여 스프링 컨텍스트를 초기화한다. 여기서 사용된 AppConfig 클래스는 스프링 설정 정보를 포함하고, 이를 기반으로 스프링 빈이 생성되고 관리된다.
  3. getBean() 메서드: 이 메서드를 사용하여 애플리케이션 컨텍스트로부터 빈을 조회할 수 있다. 개발자는 빈의 이름과 타입을 명시함으로써 필요한 빈을 안전하게 가져올 수 있다.
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, "member1", Grade.VIP);
        memberService.join(member);

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

        System.out.println("order =" + order);
    }
}