Ананасы из бобов

Весенние бобовые аннотации

1. обзор

В этой статье мы обсудим большинствоcommon Spring bean annotations, используемых для определения различных типов bean-компонентов.

Есть несколько способов настроить bean-компоненты в контейнере Spring. Мы можем объявить их, используя конфигурацию XML. Мы можем объявить bean-компоненты, используя аннотацию@Bean в классе конфигурации.

Или мы можем пометить класс одной из аннотаций из пакетаorg.springframework.stereotype, а остальное оставить сканированию компонентов.

2. Компонент Сканирование

Spring может автоматически сканировать пакет на наличие компонентов, если включено сканирование компонентов.

@ComponentScan определяет, какойpackages to scan for classes with annotation configuration. Мы можем указать имена базовых пакетов напрямую с помощью одного из аргументовbasePackages илиvalue (value - это псевдоним дляbasePackages):

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

Также мы можем указать классы в базовых пакетах с аргументомbasePackageClasses:

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

Оба аргумента являются массивами, поэтому мы можем предоставить несколько пакетов для каждого.

Если аргумент не указан, сканирование происходит из того же пакета, в котором присутствует аннотированный класс@ComponentScan.

@ComponentScan использует функцию повторяющихся аннотаций Java 8, что означает, что мы можем пометить класс с ее помощью несколько раз:

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

В качестве альтернативы мы можем использовать@ComponentScans для указания нескольких конфигураций@ComponentScan:

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

Когдаusing XML configuration, настройка сканирования компонентов также проста:

3. @Componentс

@Component - это аннотация уровня класса. Во время сканирования компонентовSpring Framework automatically detects classes annotated with @Component.

Например:

@Component
class CarUtility {
    // ...
}

По умолчанию экземпляры bean-компонентов этого класса имеют то же имя, что и имя класса, и строчные буквы. Кроме того, мы можем указать другое имя, используя необязательный аргументvalue этой аннотации.

Поскольку@Repository,@Service,@Configuration и@Controller - все мета-аннотации@Component, они используют одно и то же поведение при именовании bean-компонентов. Кроме того, Spring автоматически подхватывает их во время сканирования компонентов.

4. @Repositoryс

Классы DAO или репозитория обычно представляют уровень доступа к базе данных в приложении и должны быть аннотированы@Repository:

@Repository
class VehicleRepository {
    // ...
}

Одним из преимуществ использования этой аннотации является то, чтоit has automatic persistence exception translation enabled. При использовании среды сохранения, такой как Hibernate, собственные исключения, генерируемые в классах, аннотированных@Repository, будут автоматически транслироваться в подклассы SpringDataAccessExeption.

To enable exception translation, нам нужно объявить наш собственный bean-компонентPersistenceExceptionTranslationPostProcessor:

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

Обратите внимание, что в большинстве случаев Spring выполняет вышеуказанный шаг автоматически.

Или через конфигурацию XML:

5. @Serviceс

business logic приложения обычно находится на уровне сервиса, поэтому мы будем использовать аннотацию@Service, чтобы указать, что класс принадлежит этому уровню:

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

6. @Controllerс

@Controller - это аннотация уровня класса, которая сообщает Spring Framework, что этот класс служитcontroller in Spring MVC:

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

7. @Configurationс

КлассыConfiguration могут быть аннотированыcontain bean definition methods с помощью@Bean:

@Configuration
class VehicleFactoryConfig {

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

}

8. Стереотипные аннотации и АОП

Когда мы используем стереотипные аннотации Spring, легко создать pointcut, нацеленный на все классы, которые имеют определенный стереотип.

Например, предположим, что мы хотим измерить время выполнения методов из уровня DAO. Мы создадим следующий аспект (используя аннотации AspectJ), используя стереотип@Repository:

@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;
    }
}

В этом примере мы создали pointcut, который соответствует всем методам в классах, аннотированных@Repository. Мы использовали совет@Around, чтобы затем нацелить этот pointcut и определить время выполнения перехваченных вызовов методов.

Используя этот подход, мы можем добавить ведение журнала, управление производительностью, аудит или другие варианты поведения для каждого уровня приложения.

9. Заключение

В этой статье мы рассмотрели аннотации стереотипов Spring и узнали, какую семантику они представляют.

Мы также узнали, как использовать компонентное сканирование, чтобы сообщить контейнеру, где найти аннотированные классы.

Наконец, мы увидели, как эти аннотацииlead to a clean, layered design и разделение между проблемами приложения. Они также уменьшают конфигурацию, поскольку нам больше не нужно явно определять компоненты вручную.

Как обычно доступны примерыover on GitHub.