작성
·
27
0
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)
[질문 내용]
package hello.core.scope;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import lombok.Getter;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import static org.assertj.core.api.Assertions.*;
public class SingletonWithPrototypeTest {
@Test
void SingletonClientUsePrototype() {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(ClientBean.class, PrototypeBean.class);
ClientBean ClientBean1 = ac.getBean(ClientBean.class);
int count1 = ClientBean1.logic();
assertThat(count1).isEqualTo(1);
ClientBean ClientBean2 = ac.getBean(ClientBean.class);
int count2 = ClientBean2.logic();
assertThat(count2).isEqualTo(1);
}
@Scope("singleton")
static class ClientBean {
@Autowired
private ObjectProvider<PrototypeBean> prototypeBeanProvider;
public int logic() {
PrototypeBean prototypeBean = prototypeBeanProvider.getObject();
prototypeBean.addCount();
return prototypeBean.getCount();
}
}
@Getter
@Scope("prototype")
@Component
static class PrototypeBean {
private int count = 0;
public void addCount() {
count++;
}
@PostConstruct
public void init() {
System.out.println("PrototypeBean.init" + this);
}
@PreDestroy
public void destroy() {
System.out.println("PrototypeBean.destroy");
}
}
}
강의에서는 AnnotationConfigApplicaionContext를 new로 생성하면서 파라미터로 ClientBean클래스를 넘겨주면서 빈에 등록한 후에 아래 ClientBean 클래스에 Provider를 사용하면서 @Autowired 를 사용 하시더군요
마찬가지로 Provider사용하기 전에 생성자 주입을 할때도 Autowired를 사용하시길래 저도 코드에 Autowired를 추가했는데, 저는 오류가 나더라구요
제가 궁금한점은 @Component어노테이션을 ClientBean클래스에 붙여주면 해결되긴 했는데 강의에선 @Component 어노테이션을 사용하지 않아도 오류가 나지 않길래 저랑 뭐가 다른건지 모르겠어서 질문 합니다. 이미 파라미터로 넘기면서 빈에 등록이 되서 다시 등록하려는거때문에 충돌이나서 그런건가요? 그렇다면 강사님 강의에서 보인 코드는 왜 오류가 나지 않는건가요? 궁금합니다 ㅠㅠ
정리하자면 강사님 강의에선 ClientBean클래스에 @Componenet를 사용하지 않고도 @Autowired를 사용했을때 오류가 나지 않지만 저는 @Autowired만 사용하면 오류가 뜹니다. 어떤 차이가 있는건지 궁금합니다.
답변 2
0
안녕하세요. keoung ko님
도움을 드리고 싶지만 질문 내용만으로는 답변을 드리기 어렵습니다.
@Autowired로 실패하는 경우가 있는 실제 동작하는 전체 프로젝트를ZIP파일로 압축해서 구글 드라이브로 공유해서 링크를 남겨주세요.
구글 드라이브 업로드 방법은 다음을 참고해주세요.
주의: 업로드시 링크에 있는 권한 문제 꼭 확인해주세요
추가로 다음 내용도 코멘트 부탁드립니다.
1. 문제 영역을 실행할 수 있는 방법
2. 문제가 어떻게 나타나는지에 대한 상세한 설명 (오류 화면, 오류 로그 포함)
링크: 공식 서포터즈
링크: 자주하는 질문
감사합니다.
0
안녕하세요, 인프런 AI 인턴입니다.
keoung ko님, 질문 주셔서 감사드립니다. ClientBean 클래스에 @Component 어노테이션을 사용하지 않고도 @Autowired를 사용했을 때 오류가 나지 않는 이유는 강의에서 사용한 ApplicationContext 설정 방식의 차이 때문일 가능성이 큽니다.
AnnotationConfigApplicationContext를 생성할 때, 강의에서 사용한 예제나 설명이 ClientBean을 스프링 컨텍스트에 직접 등록하는 방식이 아닌, 다른 설정 방식이었을 수 있습니다. 이는 주로 XML 설정 파일이나 Java Config에서 @Bean 어노테이션을 사용하여 빈을 등록하는 방법이 있을 수 있습니다.
한편, keoung ko님께서 @Autowired를 사용하실 때 오류가 발생한 것은 ClientBean이 스프링의 관리 대상이 되지 않았기 때문입니다. AnnotationConfigApplicationContext 생성 시, 파라미터로 넘기는 방법은 해당 클래스를 자동으로 @Component 스캔을 통해 등록하지 않기 때문에, @Component를 명시적으로 사용하여 스프링 컨텍스트에 빈으로 등록해 주어야 합니다. 강의에서는 이러한 방식 대신 다른 적절한 빈 등록 방법을 사용했을 가능성이 큽니다.
따라서 강의와 동일한 동작을 원하신다면 강의의 프로젝트 설정 및 @Bean 등의 구체적인 설정 방법을 한 번 더 확인해 보시는 것이 좋습니다.
추가적으로 참고할 수 있는 부분:
- Spring Boot Reference Documentation > Integration Testing
문제가 해결되길 바라며, 추가적인 질문이 있으시면 언제든지 문의 주시기 바랍니다. 감사합니다.