[Spring] 자바코드 Spring으로 전환(1)

JJoSuk·2023년 5월 31일
0
post-thumbnail

본 프로젝트 자료는 김영한님 스프링 핵심 원리 - 기본편을 참고로 제작됐습니다.

그 전까지 배우던 내용은 자바코드로만 설계를 진행했지만, 자바코드를 Spring 으로 전환하려고 한다.


기존 AppConfig, Spring기반으로 변경

// Configuration : Annotation 을 기반으로 설정 혹은 구성 정보를 의미
@Configuration
public class AppConfig {

    // Bean : 각 객체에 빈을 등록하면 스프링 컨테이너에 정보가 들어가게 된다
    @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 FixDiscountPolicy();
        return new RateDiscountPolicy();
    }
}

AppConfig 에 @Configuration 을 넣어 설정 파일로 만들고 @Bean 을 생성해 스프링 컨텐이너로 만들어 유지보수에 유용하게 바꾼다.


MemberApp 에 스프링컨테이너를 적용

public class MemberApp {

    public static void main(String[] args) {

//        ApplicationContext : 이게 컨테이너로 인식해도 된다.
//        @Configurationd을 AppConfig을 했기에 AppConfig을 들고오면 된다.
        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());
    }
}

OrderApp 에도 스프링컨테이너를 적용

public class OrderApp {

    public static void main(String[] args) {

        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 = " + order.toString());
    }
}

두 코드를 실행하면 스프링 관련 로그가 몇줄 실행되면서 기존과 동일한 결과가 출력된다.

그리고 @Bean 이 등록되면서 정상적으로 스프링컨테이너에 등록된 모습을 확인 할 수 있다.


배운 점 정리

Spring(1일차)

@Configuration

  • @Configuration이라고 하면 설정파일을 만들기 위한 Annotation or @Bean을 등록하기 위한 Annotation 이다.

  • @Configuration 을 Annotation 을 사용하면 가시적으로 설정이고, 단순하게 Bean 을 등록한다 라 생각할 수 있지만

  • @Configuration 은 단순 @Bean 을 등록하기 위한 Annotation 이 아니다.

  • @Configuration 가 @Bean 을 등록할때 싱글톤이 보장될 수 있도록 하기 위해 사용한다.

    • 그럼 저연스레 스프링컨테이너에서 @Bean 을 관리할 수 있게 된다.
  • @Configuration 을 빼고 단순 @Bean 만 등록했을 때 싱글톤 보장 받을 수 있을까?

    • @Configuration 이 빠질 경우 @Bean 은 스프링 빈으로는 등록이 되지만 싱글톤이 유지되지 않는다.
  • 또한 @Configuration 가 있고 없고 간의 출력 결과도 다른걸 알 수 있다

    • @Configuration이 있다면 Test.sample.AppConfigEnhancerBySpringCGLIBEnhancerBySpringCGLIB780402cc@6179e425
    • @Configuration이 없다면 Test.sample.AppConfig@2796aeae 의 결과를 가지게 된다. 
  • @Configuration이 붙었을때의 결과를 보면 CGLIB라는게 붙은걸 볼수있다.

    • 사실 이것은 내가 만든 클래스가 아닌 스프링에서 CGLIB라는 바이트코드 조작 라이브러리를 사용해서 AppConfig를 상속받은 임의의 클래스를 만들고 그것을 스프링 빈으로 등록했기 때문에 이런결과가 나오게 된다.
    • 이때 임의의 클래스를 통해서 싱글톤이 되는것을 유지해준다.

@Bean

  • 빈(Bean)은 스프링 컨테이너에 의해 관리되는 재사용 가능한 소프트웨어 컴포넌트이다.
  • 빈(Bean)은 인스턴스화된 객체를 의미하며, 스프링 컨테이너에 등록된 객체를 스프링 빈이라고 한다.
    • @Bean 어노테이션을 통해 메서드로부터 반환된 객체를 스프링 컨테이너에 등록한다.
  • getBean() 메서드를 통해 bean의 인스턴스를 가져올 수 있다.
  • ApplicationContext 인터페이스는 bean을 가져오는 여러 가지 방법들이 있다.

그럼 위에 사용된 스프링 켄터이너는 무엇일까?

스프링 컨테이너는 스프링 프레임워크의 핵심 컴포넌트이다.
스프링 컨테이너는 자바 객체의 생명 주기를 관리하며, 생성된 자바 객체들에게 추가적인 기능을 제공한다.
스프링에서는 자바 객체를 빈(Bean)이라 한다.

즉, 스프링 컨테이너는 내부에 존재하는 빈의 생명주기를 관리(빈의 생성, 관리, 제거 등)하며, 생성된 빈에게 추가적인 기능을 제공하는 것이다.

스프링 컨테이너는 XML, 어노테이션 기반의 자바 설정 클래스로 만들 수 있다.
스프링 부트(Spring Boot)를 사용하기 이전에는 xml을 통해 직접적으로 설정해 주어야 했지만, 스프링 부트가 등장하면서 대부분 사용하지 않게 되었다.


ApplicationContext

ApplicationContext 를 알기 앞서 BeanFactory 를 알아야 하는데,

BeanFactory는

Bean 을 생성하고 관계설정과 같은 제어역할을 담당하는 것이 BeanFactory 다. BeanFactory 는 스프링의 최상위 인터페이스이며 Spring IOC Container 의 기본 요소라고 보면 된다.

ApplicationContext 는 이런 BeanFactory 를 상속받아 구현되어 있다.


AnnotationConfigApplicationContext

  • 애노테이션 기반 스프링 컨테이너 생성할 때 자주 사용하는 구현체

정리

@Configuration과 @Bean 이용해 수동 빈 등록으로 스프링컨테이너 전환

profile
안녕하세요

0개의 댓글