2021. 9. 20. 20:01ㆍSpring
5장 컴포넌트 스캔 (자동 빈 등록)
자동 주입과 함께 사용하는 추가 기능이 컴포넌트 스캔임.
컴포넌트 스캔은 스프링이 직접 클래스를 검색해서 빈으로 등록해주는 기능.
⇒ 개발자, 유지보수자 간에 신경써야 하는 객체는 자동등록 하지 말고 수동등록 사용.
1. @Component
어노테이션으로 스캔 대상 지정
스프링이 검색해서 빈으로 등록할 수 있으려면 클래스에 @Component
어노테이션을 붙여야 함.
어노테이션에 값을 주면 해당 이름으로 빈 등록.
@Component("mDao")
public class MemberDao{ ... }
이때 값을 따로 지정하지 않으면 빈은 클래스 이름이 첫글자가 소문자인 형태로 등록.
ex) MemberDao ⇒ memberDao
2. @ComponentScan
어노테이션으로 스캔 설정
@Component 어노테이션을 붙인 클래스를 스캔해서 스프링 빈으로 등록하기 위해서는 설정 클래스에 @ComponentScan 어노테이션을 적용해야 한다.
3. 스캔대상 제외
@ComponentScan
의 excludeFilters 속성을 사용하면 스캔할 때 특성 대상을 자동 등록 대상에서 제외할 수 있다. 제외하는 방법에는 4가지 방법이 있다.
- 정규식 사용
- AspectJ 사용
- 어노테이션 사용
- 특정 타입이나 하위타입을 제외
1. 정규식 사용
@Configuration
@ComponentScan(basePackages = {"spring"}, excludeFilters = @Filter(
type = FilterType.REGEX, pattern = "spring\\..*Dao"))
public class AppCtxWithExclude{
@Bean
public MemberDao memberDao(){
return MemberDao();
}
}
@Filter
어노테이션의 type 속성값으로FilterType.REGEX
를 주었다. 이는 정규 표현식을 사용해서 제외 대상을 지정한다는 것을 의미한다.@Filter
어노테이션의 pattern 속성은 FilterType에 적용할 값을 설정하다.- 위 코드에서는 "spring."으로 시작하고, Dao로 끝나는 정규표현식을 지정했으므로, sapring.MemberDao 클래스를 컴포넌트 스캔 대상에서 제외한다.
2. AspectJ 사용
FilterType.ASPECTJ
- AspectJ 패턴은 정규식과는 다른데, 이는 7장에 자세히 있음.
- 위 코드는 "spring." *Dao" AspectJ 패턴은 spring 패키지의 Dao로 끝나는 타입을 지정한다는 정도로만 기억.
- AspectJ 패턴이 동작하려면 의존 대상에 aspectjweaver 모듈을 추가해야 함.
- ⇒ pom.xml에 추가.
3. 어노테이션 사용
⇒ java 어노테이션 정리
어노테이션 클래스
설정파일
특정 어노테이션을 붙인 타입을 컴포넌트 대상에서 제외할 수도 있다.
⇒ FilterType.ANNOTATION
위 예제에서는 @NoProduct
나 @ManualBean
어노테이션을 붙인 클래스는 컴포넌트 스캔 대상에서 제외한다.
4. 특정 타입이나 하위타입을 제외
⇒ FilterType.ASSIGNABLE_TYPE
- classes 속성에는 제외할 타입 목록을 지정한다.
※ 두개 이상의 필터를 적용
설정할 필터가 두개 이상이면 @ComponentScan
의 excludeFilters 속성에 배열을 사용해서 전달하면 됨.
4. 기본 스캔 대상
@Component
어노테이션을 붙인 클래스만 컴포넌트 스캔 대상에 포함되는 것은 아니다. 아래 어노테이션을 붙인 클래스가 컴포넌트 스캔 대상에 포함된다.
@Component
⇒ 기본
@Controller
⇒ 프레젠테이션 레이어에서 빈 객체를 만들때 사용.
교수님 말씀 받아적은거.
웹 어플리케이션 MVC에서 웹을 통해 브라우저(사용자)의 요청을 받아들이고 사용자에게 어플리케이션의 수행결과를 View에 보여주는것을 책임 지는 것. 프레젠테이션 레이어를 구현. 프로그램 전체를 지휘하는 컴포넌트를 만들때. 사용자의 요청을 다양한 방법으로 받아들이고 검증하고 어떤 처리를 할 수 있는 기능을 가지는 특별한 어노테이션 이라요.
@Service
⇒ 실제 비즈니스 로직을 구현하는 서비스 계층의 컴포넌트 객체를 만들때 사용.
교수님 말씀 받아적은거
컨트롤러가 모든 일을 안하고, 요청 처리와 관련된 일만 구현하고, 실제 비즈니스 로직을 구현하는 서비스 계층의 컴포넌트 객체를 만들때는 서비스 어노테이션을 붙혀서 만들면 자동으로 등록해줘서 돌아가는 막 그런게 된다는 겁니다.
@Repository
⇒ DB연동과 관련. DAO 계층을 만들때는 이녀석을 써요. 막 뒤에서 이런녀석들을 쓸겁니다.
@Configuration
⇒ 설정 클래스를 쓸때 사용하는 어노테이션
@Aspect
⇒ 7장에서 AOP를 할때 aspect 설정클래스를 묘사할때 쓰는거라요
@Aspect
어노테이션을 제외한 나머지 어노테이션은 실제로는 @Component
어노테이션에 대한 특수 어노테이션이다.
⇒ 예를들어 @Controller
의 구현 코드를 살펴보면 아래와 같이 @Component
어노테이션이 붙어있는것을 확인할 수 있다.
5. 컴포넌트 스캔에 따른 스캔 충돌 처리
컴포넌트 스캔을 사용해서 자동으로 빈을 등록할때는 충돌에 주의해야 한다.
크게 두 가지.
- 빈 이름 충돌과,
- 수동 등록에 따른 충돌이 발생할 수 있다.예를들어 spring 패키지와 spring2 패키지에 MemverDao 클래스가 존재하고 두 클래스 모두
@Component
어노테이션을 붙혔다고 하면 충돌 발생.해결법@Qualifier
명시자- Component value=~~,
- BeanID값 주기 등자동 등록된 빈의 이름과 같은 클래스를 수동 등록을 하게 된다면 식별자 충돌 발생.
- 5-2. 수동 등록에 따른 충돌
- ⇒ 컴포넌트 스캔 과정에서 서로 다른 타입인데 같은 빈 이름을 사용하는 경우가 있다면 둘 중하나에 명시적으로 빈 이름을 지정해서 이름 충돌을 피해야 한다.
- 5-1. 빈 이름 충돌
위와 같은 경우에는 수동 등록한 빈 이름이 우선 등록되고 자동 등록된것은 무시됨.
물론 같은 클래스 타입의 빈을 여러개 만들수 있고, 여러개 만드려면 식별자를 다르게 해서 만들면 됨.
⇒ 이때 식별자만 다르고 같은 타입의 빈이 여러개 생성한다면 의존 자동 주입하는 코드는 @Qualfier
어노테이션을 사용해서 알맞은 빈을 선택해야 함.
출처 : 최범균,『스프링5 프로그래밍 입문』, 가메출판사
'Spring' 카테고리의 다른 글
7장. AOP 프로그래밍 (0) | 2021.10.06 |
---|---|
6장. 빈 라이프사이클과 범위 (0) | 2021.10.06 |
4장. 의존 자동주입 (0) | 2021.08.11 |
3장. 스프링 DI (0) | 2021.08.11 |
2장. 컨테이너 생성 (0) | 2021.08.11 |