1. 개요

이 예제에서는 Spring의 두 가지 주요 XML 구성 요소인 <context:annotation-config>  및 <context:component-scan> 간의 차이점에 대해 알아봅니다  .

2. 빈 정의

우리 모두 알다시피 Spring은 bean 과 의존성을 정의하는 두 가지 방법인 XML 구성 과 Java 어노테이션을 제공합니다. Spring의 어노테이션을 의존성 주입 어노테이션빈 어노테이션 의 두 그룹으로 분류할 수도 있습니다 .

어노테이션을 추가하기 전에는 XML 구성 파일에서 모든 빈과 의존성을 수동으로 정의해야 했습니다. 이제 Spring의 어노테이션 덕분에 모든 빈과 의존성을 자동으로 검색하고 연결할 수 있습니다 . 따라서 최소한 빈과 의존성에 필요한 XML을 제거할 수 있습니다.

그러나 어노테이션은 활성화하지 않으면 쓸모가 없다는 점을 기억해야 합니다 . 이를 활성화하기 위해 XML 파일 위에 <context:annotation-config> 또는 <context:component-scan>  을 추가할 수 있습니다.

이 섹션에서는 <context:annotation-config> 및  <context:component-scan> 이 어노테이션을 활성화하는 방법 측면에서 서로 어떻게 다른지 살펴보겠습니다.

3. < context:annotation-config> 에 의한 어노테이션 활성화

< context:annotation-config> 어노테이션은 주로 의존성 주입 어노테이션을 활성화하는 데 사용됩니다. @Autowired , @Qualifier@PostConstruct , @PreDestroy@Resource 는 <context:annotation-config> 로 해결할 수 있는 것들 중 일부입니다  .

간단한 예를 만들어 <context:annotation-config> 가 XML 구성을 단순화하는 방법을 살펴보겠습니다.

먼저 의존성 필드가 있는 클래스를 생성해 보겠습니다.

public class UserService {
    @Autowired
    private AccountService accountService;
}
public class AccountService {}

이제 빈을 정의해 봅시다.

<bean id="accountService" class="AccountService"></bean>

<bean id="userService" class="UserService"></bean>

계속 진행하기 전에 XML에서 bean을 선언해야 한다는 점을 지적하겠습니다. <context:annotation-config>  는 애플리케이션 컨텍스트에 이미 등록된 빈에 대해서만 어노테이션을 활성화하기 때문  입니다.

여기에서 볼 수 있듯이 @Autowired 를 사용하여 accountService 필드  에 어노테이션을 달았습니다 . @Autowired 는 이 필드가 일치하는 빈에 의해 자동으로 연결되어야 하는 의존성임을 Spring에 알립니다.

@Autowired 를 사용하지 않았다면  accountService 의존성을 수동으로 설정해야 합니다 .

<bean id="userService" class="UserService">
    <property name="accountService" ref="accountService"></property>
</bean>

이제 단위 테스트에서 빈과 의존성을 참조할 수 있습니다.

@Test
public void givenContextAnnotationConfig_whenDependenciesAnnotated_thenNoXMLNeeded() {
    ApplicationContext context
      = new ClassPathXmlApplicationContext("classpath:annotationconfigvscomponentscan-beans.xml");

    UserService userService = context.getBean(UserService.class);
    AccountService accountService = context.getBean(AccountService.class);

    Assert.assertNotNull(userService);
    Assert.assertNotNull(accountService);
    Assert.assertNotNull(userService.getAccountService());
}

음, 여기에 문제가 있습니다. @Autowired  로 어노테이션을 달았지만 Spring이 accountService 를 연결하지 않는 것 같습니다 . @Autowired  가 활성화되지 않은 것 같습니다 . 이 문제를 해결하기 위해 XML 파일 위에 다음 행을 추가하기만 하면 됩니다.

<context:annotation-config/>

4. < context:component-scan> 에 의한 어노테이션 활성화

<context:annotation-config> 와 유사하게 < context : component-scan> 은 의존성 주입 어노테이션도 인식하고 처리할 수 있습니다. 또한 <context:component-scan> 은 <context:annotation-config> 가 감지하지  못하는 빈 어노테이션을 인식 합니다.

기본적으로 <context:component-scan>  은 패키지 스캔을 통해 어노테이션을 감지합니다 . 달리 말하면 어노테이션이 달린 빈이나 구성 요소를 찾기 위해 어떤 패키지를 스캔해야 하는지 Spring에 알려줍니다.

@Component @Repository , @Service , @Controller , @RestController @Configuration 은 <context:component-scan>  이 감지할 수 있는여러 가지입니다  .

이제 이전 예제를 단순화하는 방법을 살펴보겠습니다.

@Component
public class UserService {
    @Autowired
    private AccountService accountService;
}

@Component
public class AccountService {}

여기에서  @Component 어노테이션은 클래스를 bean으로 표시합니다 . 이제 XML 파일에서 모든 빈 정의를 지울 수 있습니다. 물론 <context:component-scan> 을 맨 위에 두어야 합니다.

<context:component-scan
  base-package="com.baeldung.annotationconfigvscomponentscan.components" />

마지막으로 Spring은 base-package 속성 으로 표시된 패키지 아래에서 어노테이션이 달린 빈과 의존성을 찾습니다  .

5. 결론

이 예제에서는 <context:annotation-config><context:component-scan> 의 차이점을 살펴보았습니다 .

항상 그렇듯이 코드 샘플은 GitHub 에 있습니다 .

Generic footer banner