개발자

여기서 의존성 주입이 어떻게 이뤄질 수 있는 지 궁금합니다.

2024년 03월 18일조회 624

안녕하세요 이제 막 스프링부트 공부를 시작한 3학년 학생입니다. 다름이 아니라 스프링부트를 공부하던 중 아래와 같은 의문이 생겨 질문드립니다. @SpringBootApplication @ConfigurationPropertiesScan public class SburRestDemoApplication { public static void main(String[] args) { SpringApplication.run(SburRestDemoApplication.class, args); } } @ConfigurationProperties(prefix = "greeting") class Greeting { private String name; private String coffee; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getCoffee() { return coffee; } public void setCoffee(String coffee) { this.coffee = coffee; } } 제가 이해하기로는 @Component(service, repository, controller 등) 어노테이션이 클래스에 부착되어 있어야 해당 클래스의 객체를 스프링 컨테이너에 의해 의존성 주입을 할 수 있다고 알고 있는데, @ConfigurationProperties 어노테이션은 내부를 아무리 찾아도 위에서 언급한 어노테이션을 가지고 있지 않았습니다. 하지만, @RestController @RequestMapping("/greeting") class GreetingController { private final Greeting greeting; public GreetingController(Greeting greeting) { this.greeting = greeting; } @GetMapping String getGreeting() { return greeting.getName(); } @GetMapping("/coffee") String getNameAndCoffee() { return greeting.getCoffee(); } } @RestController 에 의해(@RestController는 내부에 controller 어노테이션이 있더라구요) 스프링 컨테이너로부터 의존성 주입을 받을 수 있는 GreetingController는 greeting 객체를 받아서 생성자 메서드를 실행하므로 스프링 컨테이너에서 Greeting 클래스의 객체를 의존성 주입 받을 수 있는 지 확인해보고 위에서 언급한대로 Greeting은 등록되어 있지 않으므로 오류가 날거라 예상했습니다. 하지만, 아무런 문제없이 자동으로 public GreetingController(Greeting greeting) { this.greeting = greeting; } greeting 객체가 주입이 되었고 실행되었습니다. 제가 이해한 내용이 어디서 틀렸는 지 궁금합니다.

이 질문이 도움이 되었나요?
'추천해요' 버튼을 누르면 좋은 질문이 더 많은 사람에게 노출될 수 있어요. '보충이 필요해요' 버튼을 누르면 질문자에게 질문 내용 보충을 요청하는 알림이 가요.

답변 2

인기 답변

장성호님의 프로필 사진

@ConfigurationPropertiesScan 라는 어노테이션이 SburRestDemoApplication class에 있기 때문에, Greeting 클래스가 빈으로 등록됩니다. 따라서 DI 컨테이너에 Greeting 객체가 있는 상태입니다. 그리고 GreetingController는 단일 생성자를 가지고 있기 때문에 @Autowired를 사용하지 않더라도 자동으로 생성자 기반 의존성 주입을 진행합니다. 이는 Spring 4.3 이후부터 지원되는 기능입니다. 아래 첨부한 공식 문서를 보시면, "Configures the base packages used when scanning for @ConfigurationProperties classes." 라는 문장이 있습니다. 말 그대로 base package부터 시작해서 @ConfigurationProperties가 붙은 클래스를 빈으로 자동 설정해주는 어노테이션이에요! 스프링 공식 문서 : https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/context/properties/ConfigurationPropertiesScan.html

이진호님의 프로필 사진

본문에 있는 "@Component(service, repository, controller 등) 어노테이션이 클래스에 부착되어 있어야" 에 해당하는 부분은 SburRestDemoApplication.class 위의 있는 @SpringBootApplication 내부의 @ComponentScan에 의해 동작하는 영역 입니다. 그리고 질문 주신 Greeting.class는 왜 빈으로 등록되어서 사용이 되는가에 대한 것은 SburRestDemoApplication.class 위의 있는 ```@ConfigurationPropertiesScan``` 에 의해 @ConfigurationProperties 가 붙은 클래스를 찾아 값을 주입후 빈으로 등록 되기에 동작 했던것 입니다.

지금 가입하면 모든 질문의 답변을 볼 수 있어요!

현직자들의 명쾌한 답변을 얻을 수 있어요.

또는

이미 회원이신가요?

AI 답변
커리어리 AI 봇 프로필 이미지

커리어리 AI 봇

GPT가 달아주는 답변입니다.

2024년 03월 18일

스프링 부트 환경에서 `@ConfigurationProperties`를 사용하면 해당 프로퍼티 클래스는 컴포넌트 스캔의 대상이 되어 Bean으로 등록됩니다. 그래서 `@Component`와 같은 어노테이션이 따로 붙지 않아도 스프링 컨테이너에 의해 관리되기 때문에, 다른 Bean에서 의존성 주입을 받을 수 있습니다. 사실상, `@ConfigurationProperties` 어노테이션은 스프링 부트에서 제공하는 특별한 기능 중 하나로, 애플리케이션의 환경설정 정보를 쉽게 바인딩하고 관리할 수 있도록 해줍니다. 그러니까 이 것은 애플리케이션 프로퍼티 파일(application.yml 또는 application.properties)에 정의된 값을 해당 클래스(예: Greeting)의 필드에 자동으로 바인딩합니다. 또한, `@ConfigurationPropertiesScan` 어노테이션을 메인 클래스에 추가함으로써 따로 지정하지 않아도 패키지 내의 모든 `@ConfigurationProperties`가 스캔 대상이 됩니다. 그렇기 때문에 GreetingController에서 Greeting 객체를 생성자로 주입받을 수 있었던 것입니다.

목록으로

지금 가입하면 모든 질문의 답변을 볼 수 있어요!