Skip to content

@Configuration과 바이트코드 조작의 마법 #25

@mingsound21

Description

@mingsound21

@configuration과 바이트코드 조작의 마법

  • 스프링 컨테이너는 싱글톤 레지스트리.
  • 스프링이 자바 코드까지 어떻게 하기는 어렵다!
  • 그래서 스프링이 클래스의 바이트코드를 조작하는 라이브러리를 사용한다.
  • 이전에 @configuration과 싱글톤에서 MemberRepository가 3번 호출이 아닌 1번만 호출되었던 이유를 알아보자.

TEST

@Test
    void configurationDeep() throws Exception {
        //given
        ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
        AppConfig bean = ac.getBean(AppConfig.class);

        //when
        System.out.println("bean.getClass() = " + bean.getClass());// bean.getClass() = class hello.core.AppConfig$$SpringCGLIB$$0
        // 순수한 클래스인 경우 : class hello.core.AppConfig
        // xxxCGLIB : 내가 만든 클래스가 아니라 스프링이 CGLIB라는 바이트코드 조작 라이브러리를 사용해서 AppConfig 클래스를 상속받은 임의의 다른 클래스를 만들고, 그 다른 클래스를 스프링 빈으로 등록. 임의의 다른 클래스가 싱글톤이 보장되도록해준다.
    }
  • 순수한 클래스인 경우 : class hello.core.AppConfig

  • xxxCGLIB : 내가 만든 클래스가 아니라 스프링이 CGLIB라는 바이트코드 조작 라이브러리를 사용해서 AppConfig 클래스를 상속받은 임의의 다른 클래스를 만들고, 그 다른 클래스를 스프링 빈으로 등록. 임의의 다른 클래스가 싱글톤이 보장되도록해준다.

  • 아마도 AppConfig@CGLIB가 이미 스프링 빈이 존재하면 빈을 반환하고, 스프링 빈이 없으면 생성해서 스프링 빈으로 등록하고 반환하는 코드가 동적으로 만들어진다.

  • 즉, @bean이 붙은 메서드마다 스프링 빈이 존재하면, 해당 빈을 반환하고 없다면 해당 메서드를 호출해서 스프링 빈으로 등록하고 반환한다.

@configuration없이 @bean만 사용한다면?

@configuration을 주석처리한 뒤, TEST 코드를 재실행해 보았다.

  • configurationDeep 재실행

    • AppConfig가 CGLIB 없이 그냥 class hello.core.AppConfig가 출력된다.
    • 또한, call MemberRepository가 3번 출력된다. = 싱글톤 보장 X
  • configurationTest 재실행

    • memberService.memberRepostory → 스프링이 빈으로 관리하지 않는 memberRepository 객체
    • orderService.memberRepository → 스프링이 빈으로 관리하지 않는 memberRepository 객체
    • 그냥 memberRepository → 스프링이 빈으로 관리하는 memberRepository 객체

    위 3개의 인스턴스 객체 주소가 다 다르다. → 싱글톤 보장 X

정리

  • @bean만 사용해도 스프링 빈으로 등록되지만, 싱글톤을 보장하지 않는다.
  • 고민하지 말고, 스프링 설정정보는 항상 @configuration을 사용하자.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions