-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
@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을 사용하자.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels