작성
·
244
2
@Test
void mySingletonTest(){
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(MySingletonTest.class);
MemberRepository getMemberRepository1 = ac.getBean("getMemberRepository1", MemberRepository.class);
System.out.println("getMemberRepository1 = " + getMemberRepository1);
MemberRepository getMemberRepository2 = ac.getBean("getMemberRepository2", MemberRepository.class);
System.out.println("getMemberRepository2 = " + getMemberRepository2);
}
static class MySingletonTest {
@Scope("singleton")
@Bean
public MemberRepository memberRepository(){
return new MemoryMemberRepository();
}
@Bean
public MemberRepository getMemberRepository1(){
return memberRepository();
}
@Bean
public MemberRepository getMemberRepository2(){
return memberRepository();
}
}
위의 코드를 실행하였을 때 싱글톤으로 적용되지 않는데, 어떤 식으로 수정을 하여야 싱글톤이 적용되나요??
MySingletonTest클래스에 @Configuration 애노테이션을 붙이면 싱글톤으로 적용되어서 나오는것은 확인하였고, 왜그런지 이해도 하였는데,,,
제가 이해가 부족한 것인지 용도를 잘못 생각 한 것인지 혼란이 옵니다
답변 1
0
안녕하세요, YMMD 님. 공식 서포터즈 codesweaver 입니다.
.
스프링 빈을 등록할 때 'Bean 이름'은 각 빈들을 구별하는 식별자로 작용합니다. (MySingletonTest 클래스의 getMemberRepository1(), getMemberRepository2()가 식별자로 적용됩니다)
.
@Configuration 을 붙일때와 아닐때 두 가지의 경우를 확인해보면, 빈 이름이 다를경우 같은 Repository 객체라 하더라도 메모리 주소가 다른것을 확인할 수 있습니다.
그러나 Bean 이름이 같다면 @Configuration의 여부와 상관없이 같은 객체(즉 싱글톤이 적용된)를 받은것을 확인할 수 있습니다.
.
감사합니다.
싱글톤 객체인지 확인하려면 예제에서 사용하신것처럼 객체를 출력해서 객체의 뒤에 붙은 해시값(MemberRepository@333333) 이 같은지를 확인하시면 됩니다.
빈 등록은 객체를 대상으로 하므로 빈 스코프 적용도 객체단위로 적용됩니다.
빈이 싱글톤인지 확인하려면 아래와 같이 동일한 빈을 여러번 호출 해서 콘솔창에 출력된 해시값이 동일하게 나오는지 확인하시면 됩니다.
MemberRepository r1= ac.getBean("memberRepsitory1", MemberRepository.class);
MemberRepository r2= ac.getBean("memberRepsitory1", MemberRepository.class);
System.out.println(r1);
System.our.println(r2);
YMMD님의 코드의 경우 식별자(memberRepository1, memberRepository2)는 서로 다른 객체로 관리됩니다, 그러나 동일한 식별자로 여러번 객체를 찾으면 동일한 객체를 반환(싱글톤) 받으실 수 있습니다.
감사합니다.
감사합니다 ^^!!
사실 제 테스트의 목적은
식별자가 다르지만 두개의 빈 모두 memberRepository()를 반환했고, memberRepository()는 SingletonScope로 되어있는 빈이라서 "아 싱글톤이니까 둘 다(getMemberRepository1, getMemberRepository2) 싱글톤이 적용 된 MemoryMemberRepository를 반환할까???" 를 확인하기위한 테스트였습니다.
정리하자면
첫번째 memberRepository빈이 new MemoryMemberRepository -> @333fa6a
두번째도 memberRepository()를 호출하여 반환값으로 하였으니까 동일하게 @333fa6a를 반환할까?
그럼 세번째도??
그렇다면 getMemberRepository1과 getMemberRepository2 둘 다 식별자는 다르지만 싱글톤스코프로 된 memberRepository()를 반환값으로 하였으니까 @333fa6a를 반환할까? 를 전제로 테스트를 시도해본 것이었습니다 ,,,
안녕하세요. 저도 이점이 궁금해서 테스트해보았는데요. 실제로 말씀하신대로 default bean 의 스코프는 singleton 이여서 해당 스코프를 그대로 붙으니 있고없고의 차이가 없습니다. 다만, 코드세이버님이 말씀해주신대로 현재 빈은 싱글톤은 적용되지면 memberRepository1 과 memberRepository2 가 각각호출될때 memberRepogitory() 가 각각 호출되어 서로 다른 빈이호출되는거같습니다.
여기서 CGLib 을 가지고 바이트코드내부에서 빈들끼리 유일한 싱글톤을 유지시키는 @Configuration 을 붙이면 의도하신 테스트가 정상적으로 작동될것으로 보입니다
답변감사합니다, codesweaver님 ^^
설명해주신 내용으로 빈 식별자가 다르니까 메모리 주소가 다른것 이해하였습니다.
혹시 위의 코드가 같은 빈인지 확인 할 수 있는 방법이 잘못되었나요?
아니면 메모리 주소가 각각 다른것을 가지고있다면 싱글톤으로 생성이 되지 않았다는것인가요?
이전 강의들에서 같은 객체인지 확인하는 방법으로 위의 방법처럼 사용하였던것 같은데,,,
코드보다가 혹시나해서 그러는데,,, 빈 스코프 적용은 클래스단위에서만 해당되는건가요??!!