스프링은 자동으로 스프링 빈을 등록하게 해주는 @ComponentScan
애노테이션을 통해 컴포넌트 스캔이 가능하며, @Autowired
애노테이션을 통해 자동 의존관계 주입도 가능하다.
@ComponentScan
: @Component
애노테이션이 붙은 모든 클래스를 스프링 빈으로 등록한다.
스프링 빈의 기본 이름은 클래스명을 사용하되 맨 앞글자는 소문자를 사용한다.
springComponent
@Component("anyThing")
컴포넌트 스캔 기본 대상
@Component
: 컴포넌트 스캔에서 사용@Controller
: 스프링 MVC 컨트롤러에서 사용@Service
: 스프링 비즈니스 로직에서 사용@Repository
: 스프링 데이터 접근 계층에서 사용@Configuration
: 스프링 설정 정보에서 사용
@Autowired
의존관계를 자동으로 주입해주는 애노테이션으로, 생성자에 지정해준다. 그럼 스프링 컨테이너가 자동으로 해당 스프링 빈을 찾아 주입해준다.
❗ 생성자가 하나일 경우,
@Autowired
애노테이션 생략이 가능하다.
컴포넌트 스캔의 대상이 모든 자바 클래스일 경우, 시간이 오래 걸리기에 꼭 필요한 위치부터 탐색할 수 있도록 시작 위치를 지정할 수 있다.
@ComponentScan(
basePackages = "xxxxx.xxxxx",
}
basePackages
통해 시작 위치를 지정할 수도 있지만, 지정하지 않으면 @ComponentScan
이 붙은 설정 정보 클래스의 패키지가 시작 위치가 된다.
❗ 설정 정보 클래스의 위치를 프로젝트 최상단에 두는 것을 권장한다.
@ComponentScan(
includeFilters = @Filter(type = FilterType.ANNOTATION, classes = xxxxx.class),
excludeFilters = @Filter(type = FilterType.ANNOTATION, classes = xxxxx.class)
)
FilterType은 5가지 옵션이 있다.
ANNOTATION
: 기본값, 애노테이션을 인식해서 동작한다.
ex) org.example.SomeAnnotation
ASSIGNABLE_TYPE
: 지정한 타입과 자식 타입을 인식해서 동작한다.
ex) org.example.SomeClass
ASPECTJ
: AspectJ 패턴 사용
ex) org.example..*Service+
REGEX
: 정규 표현식
ex) org.example.Default.*
CUSTOM
: TypeFilter 이라는 인터페이스를 구현해서 처리
ex) org.example.MyTypeFilter
만약, 컴포넌트 스캔 과정에 있어 같은 이름을 가진 빈이 있으면 어떻게 될까?
두 가지 상황이 주어졌을 때, 비교해보자.
컴포넌트 스캔에 의해 자동으로 스프링 빈이 등록되는데, 이름이 같은 경우 스프링은 오류를 발생시킨다.
ConflictingBeanDefinitionException
예외 발생수동으로 등록한 빈과 자동으로 등록한 빈이 충돌이 나면 다음과 같은 메세지가 출력한다.
Consider renaming one of the beans or enabling overriding by setting
spring.main.allow-bean-definition-overriding=true
resources/application.properties
➔ spring.main.allow-bean-definition-overriding=true
설정을 통해 해결할 수 있다.
Overriding bean definition for bean 'memoryMemberRepository' with a different
definition: replacing
그러면 다음과 같은 로그메세지와 함께 수동으로 등록한 빈이 자동으로 등록한 빈을 오버라이딩한다.
❗
spring.main.allow-bean-definition-overriding=false
가 기본값이다.
📌 본 포스트는 스프링 핵심 원리 - 기본편 통해 학습한 내용을 요약 및 정리한 것입니다.