1. 개요

이 예제에서는 다양한 유형의 빈을 정의하는 데 사용되는 가장 일반적인 Spring 빈 어노테이션 에 대해 설명합니다.

Spring 컨테이너에서 Bean을 구성하는 방법에는 여러 가지가 있습니다. 먼저 XML 구성을 사용하여 선언할 수 있습니다. 구성 클래스에서 @Bean 어노테이션을 사용하여 빈을 선언할 수도 있습니다 .

마지막으로 org.springframework.stereotype 패키지 의 어노테이션 중 하나로 클래스를 표시하고 나머지는 컴포넌트 스캐닝에 맡길 수 있습니다.

2. 부품 스캐닝

컴포넌트 스캐닝이 활성화되면 Spring은 자동으로 패키지에서 빈을 스캔할 수 있습니다.

@ComponentScan 은 어노테이션 구성으로 클래스를 스캔 할 패키지를 구성합니다 . basePackages 또는 인수 중 하나를 사용하여 기본 패키지 이름을 직접 지정할 수 있습니다 ( value 는 basePackages 의 별칭 임 ).

@Configuration
@ComponentScan(basePackages = "com.baeldung.annotations")
class VehicleFactoryConfig {}

또한 basePackageClasses 인수를 사용하여 기본 패키지의 클래스를 가리킬 수 있습니다.

@Configuration
@ComponentScan(basePackageClasses = VehicleFactoryConfig.class)
class VehicleFactoryConfig {}

두 인수 모두 배열이므로 각각에 대해 여러 패키지를 제공할 수 있습니다.

인수를 지정하지 않으면 @ComponentScan 어노테이션 클래스가 있는 동일한 패키지에서 스캔이 발생합니다 .

@ComponentScan 은 Java 8 반복 어노테이션 기능을 활용하므로 클래스를 여러 번 표시할 수 있습니다.

@Configuration
@ComponentScan(basePackages = "com.baeldung.annotations")
@ComponentScan(basePackageClasses = VehicleFactoryConfig.class)
class VehicleFactoryConfig {}

또는 @ComponentScan 을 사용하여 여러 @ComponentScan 구성을 지정할 수 있습니다.

@Configuration
@ComponentScans({ 
  @ComponentScan(basePackages = "com.baeldung.annotations"), 
  @ComponentScan(basePackageClasses = VehicleFactoryConfig.class)
})
class VehicleFactoryConfig {}

XML 구성을 사용할구성 요소 스캔은 다음과 같이 쉽습니다.

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

3. @컴포넌트

@Component 는 클래스 수준 어노테이션입니다. 컴포넌트 스캔 중에 Spring Framework는 @Component 로 어노테이션이 달린 클래스를 자동으로 감지합니다 .

@Component
class CarUtility {
    // ...
}

기본적으로 이 클래스의 빈 인스턴스는 소문자 이니셜을 가진 클래스 이름과 동일한 이름을 갖습니다. 또한 이 어노테이션 의 선택적 인수를 사용하여 다른 이름을 지정할 수 있습니다 .

@Repository , @Service , @Configuration , @Controller 는 모두 @Component 의 메타 어노테이션 이므로 동일한 빈 이름 지정 동작을 공유합니다. Spring은 또한 컴포넌트 스캐닝 프로세스 동안 자동으로 선택합니다.

4. @리포지토리

DAO 또는 Repository 클래스는 일반적으로 애플리케이션의 데이터베이스 액세스 계층을 나타내며 @Repository로 어노테이션을 달아야 합니다.

@Repository
class VehicleRepository {
    // ...
}

이 어노테이션을 사용하는 한 가지 이점 은 자동 지속성 예외 변환이 활성화되어 있다는 것 입니다. Hibernate와 같은 지속성 프레임워크를 사용할 때 @Repository 로 어노테이션이 달린 클래스 내에서 발생하는 기본 예외는 자동으로 Spring의 DataAccessExeption 의 하위 클래스로 변환됩니다 .

예외 번역을 활성화하려면 고유한 PersistenceExceptionTranslationPostProcessor을 선언해야 합니다 .

@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
    return new PersistenceExceptionTranslationPostProcessor();
}

대부분의 경우 Spring은 위의 단계를 자동으로 수행합니다.

또는 XML 구성을 통해:

<bean class=
  "org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

5. @서비스

애플리케이션 의 비즈니스 로직 은 일반적으로 서비스 계층 내에 있으므로 @Service  어노테이션을 사용하여 클래스가 해당 계층에 속함을 나타냅니다.

@Service
public class VehicleService {
    // ...    
}

6. @컨트롤러

@Controller 는 이 클래스 가 Spring MVC에서 컨트롤러 역할을 한다는 것을 Spring Framework에 알려주는 클래스 수준 어노테이션입니다 .

@Controller
public class VehicleController {
    // ...
}

7. @구성

구성 클래스 에는 @Bean 어노테이션이 달린 빈 정의 메서드가 포함될 수 있습니다 .

@Configuration
class VehicleFactoryConfig {

    @Bean
    Engine engine() {
        return new Engine();
    }

}

8. 스테레오타입 어노테이션과 AOP

Spring 스테레오타입 어노테이션을 사용할 때 특정 스테레오타입을 가진 모든 클래스를 대상으로 하는 포인트컷을 쉽게 생성할 수 있습니다.

예를 들어 DAO 계층에서 메서드의 실행 시간을 측정하려고 한다고 가정합니다. @Repository 스테레오타입 을 활용하여 다음 측면을 생성합니다(AspectJ 어노테이션 사용) .

@Aspect
@Component
public class PerformanceAspect {
    @Pointcut("within(@org.springframework.stereotype.Repository *)")
    public void repositoryClassMethods() {};

    @Around("repositoryClassMethods()")
    public Object measureMethodExecutionTime(ProceedingJoinPoint joinPoint) 
      throws Throwable {
        long start = System.nanoTime();
        Object returnValue = joinPoint.proceed();
        long end = System.nanoTime();
        String methodName = joinPoint.getSignature().getName();
        System.out.println(
          "Execution of " + methodName + " took " + 
          TimeUnit.NANOSECONDS.toMillis(end - start) + " ms");
        return returnValue;
    }
}

이 예제에서는 @Repository 어노테이션이 달린 클래스의 모든 메서드와 일치하는 포인트컷을 만들었습니다 . 그런 다음 @Around 조언을 사용하여 해당 포인트컷을 대상으로 하고 가로채는 메서드 호출의 실행 시간을 결정했습니다.

또한 이 접근 방식을 사용하여 로깅, 성능 관리, 감사 및 기타 동작을 각 애플리케이션 계층에 추가할 수 있습니다.

9. 결론

이 기사에서 우리는 Spring 스테레오타입 어노테이션을 조사하고 각각이 나타내는 의미의 유형에 대해 논의했습니다.

또한 컴포넌트 스캐닝을 사용하여 어노테이션이 달린 클래스를 찾을 위치를 컨테이너에 알려주는 방법을 배웠습니다.

마지막으로 이러한 어노테이션이 어떻게 깔끔하고 계층화된 디자인으로 연결되고 애플리케이션의 관심사를 분리하는지 배웠습니다. 또한 더 이상 수동으로 빈을 명시적으로 정의할 필요가 없으므로 구성을 더 작게 만듭니다.

평소와 같이 예제는 GitHub에서 사용할 수 있습니다 .

« 이전
스프링 데이터 어노테이션
Generic footer banner