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