Блог создается при поддержке Failover Bar и Anarchic Pro

Аннотации Bean в Spring

October 29, 2023 . 5 минут на чтение статьи

В Spring можно использовать несколько разных типов бинов. Когда-то в древности, все эти типы объявлялись в XML, но теперь мы можем полностью перейти на аннотации в Java-коде.

Самый простой способ узнать, какие вообще существуют аннотации - заглянуть внутрь пакета org.springframework.stereotype. Кроме того, можно поставить и голую аннотацию @Bean, это тоже сработает.

@ComponentScan

Перечислять все существующие в проекте компоненты - нудно. Мы не за тем учились на разработчиков, чтобы вручную делать нудную работу.

Аннотация @ComponentScan занимается сканированием компонентов: пробегает по выбранным пакетам и ищет бины. Все бины автоматически подключаются в проект.

Пакеты указываются через параметр basePackages (и через его алиас value). Классы по-отдельности все еще можно указывать через basePackageClasses. Все эти аннотации можно савлить в кучу в один класс. Кроме того, каждый из этих параметров является массивом.

@Configuration
@ComponentScan(basePackages = "guru.oleg")
@ComponentScan(basePackageClasses = JetFactoryConfig.class)
class JetFactoryConfig {}

Если у вас старая версия Java, то можно собирать @ComponentScan в пачки, используя @ComponentScans:

@Configuration
@ComponentScans({ 
  @ComponentScan(basePackages = "guru.oleg"), 
  @ComponentScan(basePackageClasses = JetFactoryConfig.class)
})
class JetFactoryConfig {}

Если же вы сторонник некрофилии, то всегда можно вернуться на XML. XML-некрофилия пока что не запрещена законами РФ, только законами вкуса и здравого смысла.

<context:component-scan base-package="guru.oleg" />

Что почитать?

@Component

Когда Spring сканирует компоненты, он ищет аннотацию @Component.

@Component
class JetManager {
    // ...
}

Как вы знаете, у бинов есть собственные названия. В данном случае они получаются из наименования класса, приведением его к нижнему регистру (в данном случае, имя будет "jetmanager"). Чтобы различать между собой компоненты, созданные из одинаково называющихся классов, можно использовать параметр value:

@Component(value = "jetworker")
class JetManager {
    // ...
}

Все аннотации, унаследованные от @Component, имеют точно такие же параметры. Посмотреть наследников можно в вашем любимом IDE, но можно сходу назвать несколько самых популярных: @Configuration, @Service, @Controller, @Repository. Правила автоматического обнаружения работают на них похожим способом.

Что почитать?

  • Официальная документация @Component

@Repository

Аннотация @Repository указвает на сущности, работающие с базой данных. Как именно они будут работать с базой не касается этой аннотации и зависит от типа репозитория.

@Repository
class JetRepository {
    // ...
}

Тем не менее, аннотация приносит несколько интересных ништяков. Например, все исключения, которые выбрасываются изнутри такого класса, превращаются в подклассы DataAccessExeption.

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

Если по какой-то причине магия трансляции исключений не срабатывает, можно заставить её проявиться вручную, зарегистрировав соответствующий постпроцессор:

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

XML-некрофилы тоже могут регистрировать постпроцессоры. Ни в чем себе не отказывайте.

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

Что почитать?

@Service

В MVC фреймворках есть типичная проблема: надо понять, что считать "бизнес-логикой", а что - низкоуровневыми деталями реализации. Никто в этом тебе не поможет.

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

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

Делать вы это не обязаны, с чисто технческой точки зрения. Можно положить свой код куда-нибудь еще, и он точно так же заработает. А вот с точки зрения красоты и понятности кода, идея хороша. В особенности, если вы следуете идеям DDD (Domain Driven Design).

Что почитать?

@Controller

Spring используется, в основном, для написания микросервисов и админок с веб-интерфейсом. Для того, чтобы админки было проще писать, в Spring встроен простой веб-фреймворк под общим названием Spring MVC.

Как понятно из названия, при реализации архитектурного паттерна MVC, вам нужно будет написать свой контроллер и как-то его пометить. В отличие от сервисов, делать это обязательно, это часть механики.

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

Что почитать?

@Configuration

Внутри конфигураций, помеченных как @Configuration можно использовать аннотацию @Bean и производные от неё.

@Configuration
class JetConfig {

    @Bean
    Chassis chassis() {
        return new Chassis();
    }

}

Что почитать?

@Aspect, @Pointcut, @Around

Аспектно-ориентированное программирование - большая интересная тема, открывающая возможности, которые без Spring обычно невозможны. К сожалению, объяснить работу этого механизма в одном маленьком абзаце невозможно.

Вкратце, мы можем создать новый аспект, помеченный аннотацией @Aspect. После этого, с помощью аннотации @Pointcut мы можем указать, в классы какого типа мы будем вмешиваться. И потом, с помощью аннотации @Around мы можем обернуть выбранные методы во временные объертки, которые существуют только во время работы приложения.

Подробности работы этой технологии будут рассмотрены в отдельной статье.

Что почитать?

Выводы

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

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

Тем не менее, изучение Spring на этом прекращать не стоит. Самая главная фича фреймворка в том, что он умеет подхватывать ваши классы, размеченные этими аннотациями, и творить поверх них дикую безумную магию. Которую самостоятельно писать долго и сложно. Про то, как пользоваться этими возможностями - будет в новых статьях серии.



Не забывайте подписаться на наши ресурсы, там есть ништяки:

  • CodCraft - Youtube-канал от автора этого гайда
  • Оправдания от Олега - Telegram-чат автора (общий, про всё на свете)
  • Javawatch - Telegram-канал про Java
  • Telegram-канал Failover Bar - единственный в Санкт-Петербурге (а может, и в России вообще) бар для разработчиков. Мы здесь постоянно встречаемся и разговариваем про Java.