Рубрики
Без рубрики

Аннотации к весенним бобам

Узнайте, как и когда использовать стандартные аннотации Spring bean – @Component, @Repository, @Service и @Controller.

Автор оригинала: baeldung.

1. Обзор

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

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

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

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

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

@ComponentScan настраивает, какие пакеты сканировать на наличие классов с конфигурацией аннотаций . Мы можем указать имена базовых пакетов непосредственно с помощью одного из аргументов base Packages или value ( value является псевдонимом для базовых пакетов ):

@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 , сканирование компонентов настройки так же просто:

3. @Компонент

@Component – это аннотация уровня класса. Во время сканирования компонентов Spring Framework автоматически обнаруживает классы, аннотированные @Component .

Например:

@Component
class CarUtility {
    // ...
}

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

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

4. @Репозиторий

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

@Repository
class VehicleRepository {
    // ...
}

Одним из преимуществ использования этой аннотации является то, что в ней включен автоматический перевод исключений сохранения . При использовании фреймворка персистентности, такого как Hibernate, собственные исключения, создаваемые в классах, аннотированных @Repository , будут автоматически переведены в подклассы Spring DataAccessExeption .

Чтобы включить перевод исключений , нам нужно объявить наш собственный PersistenceExceptionTranslationPostProcessor bean:

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

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

Или с помощью конфигурации XML:

5. @Сервис

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

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

6. @Контроллер

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

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

7. @Конфигурация

Конфигурация классы могут содержать методы определения компонентов аннотированные с помощью @Bean :

@Configuration
class VehicleFactoryConfig {

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

}

8. Аннотации стереотипов и АОП

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

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

@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. Заключение

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

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

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

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