Spring Ch 1. IoC 컨테이너(2) - Component와 Autowired


Component

  • Component-scan에 의해 Bean으로 등록되는 개발자가 직접 작성한 클래스.
  • @Controller, @Service, @Repository는 @Component를 확장한 annotation이며 이러한 Annotation이 등록된 컴포넌트들은 컨테이너에 의해 의존성이 주입된다.
  • ComponentScan에는 아래와 같이 다양한 설정들이 있다.

basePackages

  • 기본적으로 컴포넌트 스캔은 basePackage로 등록된 클래스를 기준으로 하여 작동한다.
  • 컴포넌트 스캔은 등록된 클래스가 존재하는 폴더부터 하위폴더로 진행되므로 상위 폴더에 대해서는 스캔 되지 않는다.
  • basePackage의 기본값은 component-scan을 사용하는 configuration 설정 파일의 폴더.

useDefaultFilters

  • useDefaultFilters의 기본 값은 true이며 Annotation이 사용된 객체를 컨테이너에 등록한다.
  • useDefaultFilters의 값을 false로 설정할 경우 @Component 어노테이션을 컨테이너에서 제외하고 @Controller 어노테이션이 등록된 클래스만을 등록한다.

includeFilters와 excludeFilters

  • 특정 Component Annoation에 대한 설정을 할 수 있다.
  • 컨테이너는 Filter의 조건을 만족하는 클래스를 추가/제외하며 다음의 필터 타입 지정을 할 수 있다.
    • ANNOTATION: 특정 어노테이션에 대해 필터를 적용한다.
    • ASPECTJ: 특정 package의 객체에 대해 필터를 적용한다.
    • ASSIGNABLE_TYPE: 특정 클래스에 대해 필터를 적용한다.
    • REGEX: 글자가 포함된 package와 객체명에 대해 필터를 적용한다.
    • CUSTOM: TypeFiler 인터페이스로 작성한 필터를 적용한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
@ComponentScan(
basePackages = "com.package",
useDefaultFilters = false,
includeFilters={
@Filter(
type = FilterType.ANNOTATION,
classes = {Component.class, Repository.class} //@component, @Repository 어노테이션이 적용된 개체를 추가한다.
)
}
)
public class Config{
...
}

Annotation

  • 클래스, 메소드, 객체에 특정 의미를 부여하는 자바 구문.
  • 자바 코드에 @로 시작하는 구문을 주석처럼 달아 의존성 주입이 가능하도록 한다.
  • Annotation은 Bean의 등록에 있어 Xml을 통한 등록보다 낮은 우선순위를 갖는다.

※ Xml과 Annotation의 비교

  • xml configuration file을 사용한 빈의 등록은 xml파일의 수정만으로도 빈 설정을 변경할 수 있지만 등록하고자하는 빈이 많아질 경우 수정이 쉽지 않다는 단점이 나타난다.
  • Annotation은 애플리케이션에 등록된 Bean과 의존관계를 한눈에 볼 수 없다는 단점이 있지만 소스코드와 메타데이터가 결합되므로 XML문서에 접근하지 않고도 빈의 등록이 가능해 편리하다.
  • 시스템 전반에 영향을 주고 이후 변경 가능성이 있는 메타데이터는 코드로부터 분리되는 것이 유지보수성에 좋다. (xml로 등록)
  • 변경 가능성이 없는 메타데이터는 Annotation 기반의 Bean 설정으로 생산성을 향상 시키는 것이 좋다.

Autowired

  • 각 타입에 맞는 Bean을 IoC컨테이너로부터 찾아 주입하는 annotation.
  • 생성자, set함수, 필드에 Autowired 어노테이션을 붙여 사용할 수 있으며 스프링 4.3버전부터는 생성자에 Autowired를 붙이지 않아도 객체가 주입된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Service
public class Service{

@Autowired //필드 객체의 Injection
private Repository repository;

@Autowired //Set함수의 Injection
public void setRepository(Repository repository){
this.repository = repository;
}

//@Autowired //생성자의 Injection (생략 가능)
public Service(Repository repository){
this.repository = repository;
}
}

댓글