자체 Test 중 싱글톤 확인 안되는 것 같습니다.
412
작성한 질문수 12
싱글톤과 Configuration이 무관하다는 글을 읽고 Test를 하던 중에 다음과 같이 짜봤습니다. (@Bean만 달려도 Singleton 보장이 된다) Test 클래스에 작성중입니다.
interface Example {
String getMsg();
}
static class TestMessage {
private String msg = "No Setter String";
public TestMessage(){
System.out.println("msg = " + msg);
System.out.println(this);
}
public String getMsg() {
return this.msg;
}
}
static class ChildExample implements Example {
private TestMessage testMessage;
@Autowired
public ChildExample(TestMessage testMessage) {
this.testMessage = testMessage;
}
@Override
public String getMsg() {
return this.testMessage.getMsg();
}
}이렇게 세팅을 한 후 다음과 같이 Configuration 클래스를 만들어 봤습니다.
static class SingletonAndConfigurationAnnotationTest {
@Bean
public TestMessage testMessage() {
return new TestMessage();
}
@Bean
public Example example() {
return new ChildExample(new TestMessage());
}
}그리고 다음과 같은 테스트 코드를 작성해봤습니다.
@Test
@DisplayName("안녕안녕")
void testA() {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SingletonAndConfigurationAnnotationTest.class);
TestMessage bean1 = ac.getBean(TestMessage.class);
ChildExample bean2 = ac.getBean(ChildExample.class);
Assertions.assertThat(bean1).isSameAs(bean2.testMessage);
}저는 TestMessage 가 우선 싱글톤으로 관리가 되므로, ChildExample 에는 그 싱글톤 TestMessage 객체가 의존성 주입이 될 것이라고 생각을 했습니다. 그리고 Configuration Annotation의 유무 차이를 실험해보려 했는데 실험 해보기도 전에 저 테스트 코드가 Fail을 하네요.. 아무리 생각해도 왜 두 객체가 다른지 모르겠습니다. 싱글톤으로 관리가 되어서 두 TestMessage는 같아야 하지 않나요? 로그에서도 다른 모습이 확인됩니다. (Configuration 무관하다 하셨지만 혹시 몰라 달아봤는데도 fail이 뜹니다)
11:34:02.853 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'testMessage'
msg = You can't edit this
com.example.basicprinciple.MyTest$TestMessage@5bf8fa12
11:34:02.858 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'example'
msg = You can't edit this
com.example.basicprinciple.MyTest$TestMessage@b2c5e07왜 둘이 다른지 도움을 주실 수 있으실까요?
2.
또한 ComponentScan 에 관해서도 궁금한 점이 있습니다.
@ComponentScan(
basePackages = "com.example.basicprinciple"
)
public class AutoAppConfig {
}
강의에서 위와 같이 @ComponentScan을 설정해주셨습니다. 다만, 저런 방식이면 ComponentScan이 꼭 필요한가 싶어서 문의드립니다. 일반적으로 @controller, repository 등의 설정을 해놔도 다 Component로 이해를 하는데, 혹시 비즈니스 로직을 수행하는 함수들 외의 도움을 주는 Component들을 스캔하기 위함일까요?
3.
Configuration 과 Singleton이 무관하다고 해주신 것 같습니다. 혹시 강의 중 설명해주신 CGLIB을 따로 형성해서 싱글톤 관리가 되게 해주는건 @Bean 인걸까요? 만약 그렇다면, @Bean 함수의 묶음을 CGLIB 클래스로 만드는걸까요?
class XXCGLIB extends AppSprinfConfig{ // 내가 만든 Config의 자식 ...
@Override
@Bean
public Member membeRepository(){
if(ApplicationContext has MemoryMemberRepository){
return MemoryMemberRepository from Current Bean Container
}else{
build MemoryMemberRepository from My Class return MemoryMemberRepository
}
}
}@Configuration 내부에 있는 클래스들이 다음과 같은 클래스로 바뀌어서 등록될 것으로 보인다고 강의안에서 설명해주셨는데, 저 묶음을 @Configuration으로 가져오는게 아니라면 @Bean들을 가지고 알아서 묶는건지 궁금합니다.
감사합니다.
답변 1
1
안녕하세요. kwj3591님, 공식 서포터즈 David입니다.
본 강의 '@Configuration과 바이트코드 조작의 마법'편을 참고해주세요. @Configuration이 붙은 설정 클래스에서 @Bean이 붙은 객체 생성 메서드의 동작 부분을 집중해서 봐주시면 됩니다. textMessage(), new TextMessage()의 차이점이 보이실거에요.
기본적으로 메인 메서드가 포함된 클래스에서 @ComponentSacn이 붙어 있습니다. 따라서, 모든 컴포넌트가 등록됩니다. 그런데 별도로 @ComponentScan을 쓰는 이유는 특정 범위, 조건을 제한하여 빈을 자동으로 등록하기 위함입니다.
@Configuration으로 인해 저렇게 만들어집니다. @Configuration과 싱글톤이 무관하다는 이유는 @Configuration이 없어도 @Bean만으로 싱글톤 빈으로 등록되기 때문입니다. 조금 더 엄밀히 말하면 @Bean이 붙은 메서드가 최초 호출되어 생성되는 객체를 싱글톤 빈으로 등록하는 게 @Configuration과 무관합니다. 그러나 @Configuration은 @Bean이 붙은 메서드를 재차 호출했을 때 싱글톤을 보장하는 것과 관련이 있습니다. 이 부분이 잘 이해되지 않으시다면 @Configuration 관련 강의를 반복해서 들어주세요.
아래 글과 답변도 참고해주세요.
감사합니다.
코드 자료
0
24
2
구현체가 동적으로 정해질 때, 팩토리 기법을 사용하나요?
0
50
2
MemberService의 인터페이스를 왜 사용하는지 궁금합니다.
0
72
1
롬복 @Setter를 써야 하는 상황이 있는건가요?
0
87
1
빈 등록 메서드의 파라미터가 빈이 아니어도 되나요?
0
79
1
테스트 속도가 나중에 영향이 있을까요?
0
75
1
gradle 설정 안떠서 질문 남깁니다!
0
118
2
build.gradle로 프로젝트를 여는 이유
0
83
1
provider 사용하는 이유
0
86
1
다음 강의 뭘 들어야 할까요
0
124
2
프로토타입 빈, 직접 destroy 호출 안 할 경우
0
62
1
beanB
0
80
2
퀴즈다시풀기
0
64
1
Gradle로 바꿔도 오류가 똑같이 발생하네요 ㅠㅠ
0
90
2
"중복 등록과 충돌" 강의에서 강사님과 다른 에러가 발생합니다.
0
63
3
run 실행했는데 결과창이 이렇게 뜨네요 왜 그런건가요>
0
103
2
도메인의 정의?
0
57
1
ApplicationContext 질문입니다.
0
60
1
@Scope의 proxyMode를 사용할때 단위 테스트 방법
0
86
2
ai api 선정하기 관련 질문
0
116
2
생성자 자동주입 관련해서
0
62
1
생성자 직접 호출 vs 팩토리 메서드 패턴
0
94
2
Spring에서 SessionScope와 RequestScope는 함께 사용되나요?
1
63
1
12:25
0
75
2





