이전까지는 스프링 빈을 등록하기 위해서는 @Bean 애노테이션을 통해 직접 작성해야 했다.
@Bean
public Bean bean() {
return new Bean();
}
등록할 스프링 빈의 개수가 많지 않다면 상관이 없겠지만, 스프링 빈이 수십개 수백개라면 모두 직접 작성하여 등록하기에는 매우 비효율적이다. (단순 반복 작업이기 때문에 매우 귀찮다...)
이를 해결하기 위해 스프링 프레임워크는 직접 코드를 작성하지 않아도 스프링 빈을 등록해주는 컴포넌트 스캔 기능을 제공한다. 또한 빈 등록시 필요한 의존관계 주입도 자동으로 해주는 기능을 제공한다. 이번 포스팅에서는 컴포넌트 스캔과 의존관계 자동 주입에 대해 자세히 알아보자.
이 포스팅은 김영한님의 '스프링 핵심 원리 - 기본편' 강의에 의존하고 있습니다.
컴포넌트 스캔 (Component Scan)
@Configuration
@ComponentScan
public class AppConfig {
}
컴포넌트 스캔을 하기 위해서는 설정 정보에 @ComponentScan 애노테이션을 붙여주면 된다. 컴포넌트 스캔은 이름대로 컴포넌트들을 직접 스캔해서 @Component 애노테이션이 붙은 클래스를 직접 빈으로 등록한다. 즉, 실제 설정 정보 파일에는 빈을 등록하는 코드를 작성할 필요가 없다.
@Component 애노테이션
작성한 클래스를 스프링 빈으로 등록하기 위해서는 클래스에 @Component 애노테이션만 붙여주면 된다.
@Component
public class Bean {
private final SubBean subBean;
public Bean(SubBean subBean) {
this.subBean = subBean;
}
}
Bean 클래스를 스프링 빈 저장소에 등록한다.
생성자 자동 주입 : @Autowired
위 코드를 컴포넌트 스캔이 아닌 직접 등록을 할 경우 다음과 같이 코드를 작성하게 된다.
public Bean bean() {
return new Bean(subBean());
}
단순히, 빈을 등록하는 것뿐만 아니라, 생성자를 통해 의존관계를 주입하게 된다.
그렇다면, @Component 애노테이션을 통해 컴포넌트 스캔으로 빈을 등록하면 자동으로 의존관계도 주입되는 것일까?
아쉽게도 아니다. 즉, 생성자 주입을 하기 위해서는 추가적인 작업이 필요한데 생성자 위에 @Autowired 애노테이션만 붙여주면 자동으로 생성자 주입을 한다. (너무 간단하다!)
@Component
public class Bean {
private final SubBean subBean;
@Autowired
public Bean(SubBean subBean) {
this.subBean = subBean;
}
}
컴포넌트 스캔 동작 과정
컴포넌트 스캔(@ComponentScan)은 @Component 애노테이션이 붙은 모든 클래스를 빈으로 등록한다. 이때 빈의 이름은 클래스의 이름을 그대로 사용하되, 앞글자만 소문자로 변경한다.
@Component
public class UserService { ... }
@Component
public class Score { ... }
@Component
public class SchoolImpl { ... }
빈 이름 | 빈 객체 |
userService | UserService@x01 |
score | Score@x02 |
schoolImpl | SchoolImpl@x03 |
다음과 같이 빈 저장소에 등록되게 된다.
의존관계 자동 주입 동작 과정
@Autowired 애노테이션은 생성자에 지정하면 스프링 컨테이너는 자동으로 해당 빈을 찾아서 주입해준다. 이때 조회 방법은 타입을 이용해 조회한다. 즉, getBean(ClassType.class) 메서드와 방식이 동일하다고 보면 된다.
'WEB' 카테고리의 다른 글
[WEB] 빈 생명주기 콜백 (0) | 2022.05.10 |
---|---|
[WEB] 스프링 의존관계 자동 주입 (0) | 2022.05.03 |
[WEB] 스프링 컨테이너와 싱글톤 패턴 (0) | 2022.04.22 |
[WEB] 스프링 컨테이너 (Spring Container) (0) | 2022.04.19 |
[WEB] ClassNotFoundException: com.mysql.cj.jdbc.Driver (0) | 2022.03.02 |