public class OwnerController {
private OwnerRepository ownerRepository = new OwnerRepository();
}
// OwnerController가, 필요한 OwnerRepository의 객체를 직접 생성하는 경우
public OwnerController(OwnerRepository clinicService, VisitRepository visits) {
this.owners = clinicService;
this.visits = visits;
}
// OwnerController의 생성자에서 OwnerRepository를 인자로 받고, owners에 담고 있다.
// 이는 앞의 예시처럼 객체를 직접 생성하지 않고, 외부의 객체를 받고 있는 것이다.
스프링 IoC 컨테이너가 관리하는 객체들을 Bean 이라고 부릅니다. 스프링은 이러한 Bean들의 의존성을 관리하고, 객체를 만들어 주며, Bean으로 등록을 해 주고, 이렇게 만들어진 것들을 관리합니다. 개발자가 이 부분까지 신경쓰지 않아도, 프레임워크가 알아서 해 주는 것입니다.
그리고 스프링 IoC 컨테이너가 위와 같은 관리를 해 줍니다. 이러한 Bean들을 담고 있는 스프링 IoC 컨테이너는 두 가지 중 하나를 사용합니다.
이러한 스프링에서의 의존성 주입은 반드시 Bean으로 등록된 객체들 끼리만 가능합니다. 스프링 IoC 컨테이너는 Bean으로 등록되지 않은 객체에는 의존성 주입을 해 주지 않습니다.
둘 다 Bean으로 등록되어 있음을 확인할 수 있습니다.
그러면 특정 객체를 Bean으로 등록하는 방법은 무엇이 있을까요?
Component Scanning
Pet Clinic 프로젝트에서 main 시작 부분을 보겠습니다.
@SpringBootApplication 어노테이션이 붙어 있는데, 이를 정의한 곳으로 가 보면..
@ComponentScan 어노테이션이 붙어있음을 확인할 수 있습니다.
즉, ComponentScan 은 어느 지점부터 컴포넌트를 찾아보라고 알려 주는 것인데, 이것을 사용한 SpringBootApplication 어노테이션이 PetClinicApplication 클래스에 붙어 있습니다.
따라서, 이 PetClinicApplication 클래스부터 하위 모든 패키지들을 훑어보면서 @Component 어노테이션을 활용한 모든 클래스들을 찾고, Bean으로 등록하게 됩니다.
예를 들어 OwnerController를 살펴볼까요? 앞서 IntelliJ에서 Bean으로 등록되었다는 표시를 확인할 수 있었는데요. @Controller 어노테이션이 붙어 있었습니다.
그러면 이 @Controller 를 정의한 곳으로 가 보겠습니다.
위처럼 @Component 어노테이션이 붙어있음을 알 수 있습니다.
따라서 스프링은 OwnerController가 @Component 어노테이션을 활용했으므로 이를 Bean으로 등록해 준 것입니다.