Как написать свой стартер спринг

Время на прочтение
5 мин

Количество просмотров 47K

Большинство java-разработчиков уже познакомились с проектом Spring Boot, позволяющим быстро написать приложение, использующее различные компоненты Spring Framework (Spring MVC, Spring Data и многие другие).

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

В этой статье мне бы хотелось рассказать о том, как создаются стартеры на примере стартера для Spring-social-vkontakte. Spring Social это один из модулей Spring Framework, используемый для интеграции с социальными сетями. В проект Spring Boot включены стартеры для таких социальных сетей как Facebook (spring-boot-starter-social-facebook), Twitter (spring-boot-starter-social-twitter) и LinkedIn (spring-boot-starter-social-twitter), основанные на использовании соответствующих Social-модулей. Большинство разработчиков из СНГ интересует в первую очередь социальная сеть Вконтакте, для которой существует сторонний модуль spring-social-vkontakte. Соответственно, стартера для этого модуля еще нет. Написанием этого стартера мы и займемся в этой статье.

Краеугольным камнем инфраструктуры Spring Boot являются AutoConfiguration-классы, которые Spring Boot находит при запуске приложения и использует для автоматического создания и конфигурирования бинов.

Создадим такой класс для нашего стартера:

@Configuration
@ConditionalOnClass({SocialConfigurerAdapter.class, VKontakteConnectionFactory.class})
@ConditionalOnProperty(prefix= "ru.shadam.social-vkontakte", name = { "client-id", "client-secret"})
@AutoConfigureBefore(SocialWebAutoConfiguration.class)
@AutoConfigureAfter(WebMvcAutoConfiguration.class)
public class VKontakteAutoConfiguration {
}

Мы используем аннотации, чтобы указать SpringBoot, что наш класс является конфигурацией (@Configuration), аннотации, чтобы задать условия, при которых наш AutoConfiguration будет использоваться для создания бинов, а также аннотации, чтобы указать каково место нашей автоконфигурации в процедуре инициализации приложения.

Таким образом:

@ConditionalOnClass({SocialConfigurerAdapter.class, VKontakteConnectionFactory.class})

означает, что бины будут создаваться при наличии в classpath SocialConfigurerAdapter(входит в модуль Spring-Social) и VKontakteConnectionFactory (входит в модуль Spring-Social-Vkontakte). Таким образом, без нужных для нашего стартера зависимостей бины создаваться не будут.

@ConditionalOnProperty(prefix= "ru.shadam.social-vkontakte", name = { "client-id", "client-secret"})

означает, что бины будут создаваться только при наличии property ru.shadam.social-vkontakte.client-id и ru.shadam.social-vkontakte.client-secret.

@AutoConfigureBefore(SocialWebAutoConfiguration.class)
@AutoConfigureAfter(WebMvcAutoConfiguration.class)

означает, что наш бин будет инициализироваться после WebMvc и до SocialWeb. Это нужно, чтобы к моменту инициализации SocialWeb наши бины уже были зарегистрированы.

Теперь перейдем к тому, какие бины мы сконфигурируем в нашем AutoConfiguration.

VKontakteAutoConfiguration.java

@Configuration
@ConditionalOnClass({SocialConfigurerAdapter.class, VKontakteConnectionFactory.class})
@ConditionalOnProperty(prefix= "ru.shadam.social-vkontakte", name = { "client-id", "client-secret"})
@AutoConfigureBefore(SocialWebAutoConfiguration.class)
@AutoConfigureAfter(WebMvcAutoConfiguration.class)
public class VKontakteAutoConfiguration {

    @Configuration
    @EnableSocial
    @EnableConfigurationProperties(VKontakteProperties.class)
    @ConditionalOnWebApplication
    protected static class VKontakteConfigurationAdapter extends SocialConfigurerAdapter {

        @Autowired
        private VKontakteProperties properties;

        @Bean
        @ConditionalOnMissingBean
        @Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES)
        public VKontakte vkontakte(ConnectionRepository repository) {
            Connection<VKontakte> connection = repository.findPrimaryConnection(VKontakte.class);
            if (connection != null) {
                return connection.getApi();
            }
            return new VKontakteTemplate(this.properties.getClientId(), this.properties.getClientSecret());
        }

        private ConnectionFactory<?> createConnectionFactory() {
            return new VKontakteConnectionFactory(this.properties.getClientId(), this.properties.getClientSecret());
        }

        @Override
        public void addConnectionFactories(ConnectionFactoryConfigurer connectionFactoryConfigurer, Environment environment) {
            connectionFactoryConfigurer.addConnectionFactory(createConnectionFactory());
        }
    }
}

Расширяем SocialConfigurationAdapter, который нужен для того чтобы зарегистрировать нашу ConnectionFactory. Для этого в SocialConfigurerAdapter есть callback-метод:

addConnectionFactories(ConnectionFactoryConfigurer, Environment)

Его мы и переопределим, добавляя нашу ConnectionFactory.

Также зарегистрируем request-scoped бин Vkontakte, которые представляет собой интерфейс для доступа к API Вконтакте. При этом, если пользователь авторизуется через приложение, то операции взаимодействия с API будет выполнено с использованием auth_token.

Рассмотрим также класс VkontakteProperties, который используется для получения конфигурации из properties-файлов приложения

VkontakteProperties.java

@ConfigurationProperties(prefix = "ru.shadam.social-vkontakte")
public class VKontakteProperties  {
    private String clientId;
    private String clientSecret;

    public String getClientId() {
        return clientId;
    }

    public void setClientId(String clientId) {
        this.clientId = clientId;
    }

    public String getClientSecret() {
        return clientSecret;
    }

    public void setClientSecret(String clientSecret) {
        this.clientSecret = clientSecret;
    }
}

За получение значений из properties файлов отвечает аннотация:

@ConfigurationProperties(prefix = "ru.shadam.social-vkontakte")

Она сообщает SpringBoot, что нужно попытаться все проперти, начинающиеся с префикса ru.shadam.social-vkontakte поместить в соответствующие поля класса.

Последним нашим шагом будет создание файла, позволяющего SpringBoot найти наш AutoConfiguration класс. Для этого существует специальный файл spring.factories, который нужно поместить в META-INF папку получающегося jar-файла.

В этом файле нам надо указать наш AutoConfiguration-класс.

org.springframework.boot.autoconfigure.EnableAutoConfiguration=ru.shadam.spring.boot.vkontakte.VKontakteAutoConfiguration

Теперь, подключив получившийся jar к нашему Spring Boot проекту и задав в конфигурации ru.shadam.social-vkontakte.client-id и ru.shadam.social-vkontakte.client-secret, мы получим в нашем приложении сконфигруированные пути /connect/vkontakte и бин Vkontakte, который мы можем использовать для доступа к API Вконтакте.

Использованные материалы:

  1. docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-auto-configuration.html
  2. Ссылка на проект на github: github.com/saladinkzn/social-vkontakte-spring-boot-starter

Один из мощных механизмов Spring Boot — возможность использования «стартеров» для быстрой настройки нового проекта с предварительно сконфигурированными зависимостями.

Стартеры Spring Boot — это, предварительно упакованные наборы зависимостей и сконфигурированных бинов для обеспечения определённой функциональности. Например, доступа к базе данных или безопасности.

Возьмём мою библиотеку GodFather Telegram, которая позволяет создавать ботов для Telegram. Без стартера вам пришлось бы создать бинов 15: бин для принятия входящих событий от телеграма, бин для отправки сообщений, бин для построения сценария бота, множество инфраструктурных бинов. Без подробной документации не обойтись.

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

У клиентов стартера остаётся возможность переопределить внутренние бины, если сценарии использования выходят за рамки дефолтных настроек. Также разработчик стартера может вынести множество настроек в файл application.properties.

В этой статье мы рассмотрим, как создать собственный стартер Spring Boot. Обсудим некоторые лучшие практики и советы по созданию.

Спонсор поста

Создаем свой стартер

Написание стартера будем рассматривать на примере моей библиотеки для создания ботов GodFather Telegram.

Для начала определимся с groupId и artifactId. Все официальные стартеры придерживаются следующей схемы именования spring-boot-starter-*, где * это конкретный тип приложения.

Сторонние стартеры не должны начинаться с spring-boot, поскольку они зарезервированы для официальных стартеров от разработчиков Spring. Сторонний стартер обычно начинается с названия проекта. Например, мой стартер называется telegram-bot-spring-boot-starter.

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

Поэтому создаём пустой SpringBoot проект. Убедитесь, что в pom.xml присутствуют следующие зависимости:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

Добавьте зависимости вашей библиотеки. В моём случае их три:

<dependency>
    <groupId>dev.struchkov.godfather.telegram</groupId>
    <artifactId>telegram-consumer-simple</artifactId>
    <version>${telegram.bot.version}</version>
</dependency>
<dependency>
    <groupId>dev.struchkov.godfather.telegram</groupId>
    <artifactId>telegram-core-simple</artifactId>
    <version>${telegram.bot.version}</version>
</dependency>
<dependency>
    <groupId>dev.struchkov.godfather.telegram</groupId>
    <artifactId>telegram-sender-simple</artifactId>
    <version>${telegram.bot.version}</version>
</dependency>

Теперь создадим обычный класс конфигурации Spring с нужными бинами.

@Configuration
public class TelegramBotAutoconfiguration {

    @Bean(AUTORESPONDER_EXECUTORS_SERVICE)
    public ExecutorService executorService(
            TelegramBotAutoresponderProperty autoresponderProperty
    ) {
        return Executors.newFixedThreadPool(autoresponderProperty.getThreads());
    }
    
    ... ... ... ... ...

    @Bean
    public TelegramService telegramService(TelegramConnect telegramConnect) {
        return new TelegramServiceImpl(telegramConnect);
    }

}

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

Пока это ничем не примечательный модуль с обычным классом конфигурации, что делает его стартером? Стартером его сделает особый файл, создадим его.

В папке resources создаём папку META-INF, в ней папку spring, и в ней файл org.springframework.boot.autoconfigure.AutoConfiguration.imports.

Этот файл должен содержать перечисление конфигураций. В моём случае это одна конфигурация. Каждую конфигурацию указывайте с новой строки.

dev.struchkov.godfather.telegram.starter.config.TelegramBotAutoconfiguration

SpringBoot автоматически найдёт этот файл, возьмёт перечисленные конфигурации и создаст указанные в них бины, добавив их в контекст. Так класс конфигурации превращается в класс автоконфигурации. Вот и вся магия 🪄

Проперти классы

Если вашей библиотеке требуются какие-то конфигурационные переменные, стоит позволить передавать их через application.yml. Например, в моей библиотеке это информация данные для подключения к Telegram: токен и имя бота.

Для этого создайте класс и аннотируйте его @ConfigurationProperties или добавьте существующий через конфигурацию:

@Configuration
public class TelegramBotPropertyConfiguration {

    @Bean
    @ConfigurationProperties("telegram.bot")
    public TelegramBotConfig telegramConfig() {
        return new TelegramBotConfig();
    }
    
}

А в pom.xml добавим зависимость, которая генерирует метаданные о классах приложения, аннотированных @ConfigurationProperties.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

Этот процессор аннотаций создаст файл META-INF/spring-configuration-metadata.json, который содержит метаданные о параметрах конфигурации в классе TelegramBotConfig. Эти метаданные включают Javadoc о полях, поэтому убедитесь, что Javadoc понятен.

В Idea плагин Spring Assistant будет читать метаданные и обеспечивать подсказки для этих свойств.

Так это будет выглядеть в Idea

Также мы можем добавить некоторые свойства вручную, создав файл META-INF/additional-spring-configuration-metadata.json:

{
  "properties": [
    {
      "name": "telegram.bot.enable",
      "type": "java.lang.Boolean",
      "description": "Enables or disables Telegram Bot."
    }
  ]
}

Процессор аннотаций автоматически объединит содержимое этого файла с автоматически созданным файлом.

Conditionals

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

Например, в моем случае нет смысла поднимать бины, если пользователь не указал переменные подключения к боту в application.yml, потому что всё завязано на них.

Для решения этой проблемы существуют аннотации @Conditional...

@ConditionalOnProperty

Воспользуемся аннотацией @ConditionalOnProperty, которая проверяет наличие заполнения конкретной проперти в application.yml.

@Bean
@ConfigurationProperties("telegram.bot")
@ConditionalOnProperty(prefix = "telegram.bot", name = "token")
public TelegramBotConfig telegramConfig() {
    return new TelegramBotConfig();
}

Бин TelegramBotConfig будет создаваться, только если указана проперти telegram.bot.token.

Используя параметр аннотации value, можно указать конкретные значения проперти. В моем случае важно само наличие токена.

@ConditionalOnBean

Также воспользуемся @ConditionalOnBean, которая создаёт бин, когда в BeanFactory  присутствует указанный в @ConditionalOnBean бин.

@Bean
@ConditionalOnBean(TelegramBotConfig.class)
public TelegramDefaultConnect telegramDefaultConnect(TelegramBotConfig telegramConfig) {
    return new TelegramDefaultConnect(telegramConfig);
}

@ConditionalOnMissingBean позволяет создавать бин, если указанный бин отсутствует в BeanFactory.

@ConditionalOnClass

Создаёт бин, только если указанный класс есть в classpath. И противоположный ему @ConditionalOnMissingClass.

Несколько классов автоконфигурации

При добавлении нескольких классов автоконфигурации и использовании аннотаций @ConditionalOnBean вы столкнётесь с неожиданным поведением — условие не будет отрабатывать и бин не будет создаваться.

Это происходит, потому что Spring берёт конфигурации в произвольном порядке, и может сначала попробовать поднять бин помеченный @ConditionalOnBean, хотя бин в условии будет создан позже. Порядок классов автоконфигураций в файле никак не влияет на порядок создания бинов.

Чтобы этого избежать, используйте аннотации @AutoConfigureAfter или @AutoConfigureBefore над классом конфигурации, которые явно задают порядок создания бинов.

Опциональные бины

Еще одним полезным классом является ObjectProvider, который позволяет передавать необязательные бины. Похоже на логику работы Optional.

@Bean
@ConfigurationProperties("telegram.bot")
@ConditionalOnProperty(prefix = "telegram.bot", name = "token")
public TelegramBotConfig telegramConfig(
        ObjectProvider<ProxyConfig> proxyConfigProvider
) {
    final TelegramBotConfig telegramBotConfig = new TelegramBotConfig();

    final ProxyConfig proxyConfig = proxyConfigProvider.getIfAvailable();
    if (proxyConfig != null) {
        telegramBotConfig.setProxyConfig(proxyConfig);
    }

    return telegramBotConfig;
}

Бин ProxyConfig является опциональным. Если его не будет, мы всё равно хотим создать TelegramBotConfig. Если не использовать ObjectProvider, то приложение упадёт при старте, если бина ProxyConfig не будет.

Бины по умолчанию

Мы можем позволить пользователю переопределять наши бины, но предоставлять дефолтные бины. Для этого воспользуемся аннотацией @ConditionalOnMissingBean

@Bean
@ConditionalOnMissingBean(PersonSettingRepository.class)
public PersonSettingRepository personSettingRepository() {
    return new PersonSettingLocalRepository();
}

Обратите внимание, что в @ConditionalOnMissingBean мы указываем тот же класс, что и возвращаем. Таким образом, если пользователь стартера определит бин PersonSettingRepository, то дефолтный бин из автоконфигурации не будет создан.

Улучшаем время запуска

Классы конфигурации тоже можно аннотировать @Conditional.... И для каждого класса автоконфигурации Spring Boot оценивает условия, указанные в аннотации @Conditional..., чтобы решить, загружать ли автоконфигурацию и все необходимые в ней бины. В зависимости от размера и количества стартеров в приложении Spring Boot, это может быть очень дорогой операцией и повлиять на время запуска.

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

Чтобы метаданные генерировались, нужно добавить процессор аннотаций в стартовый модуль:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-autoconfigure-processor</artifactId>
    <optional>true</optional>
</dependency>

Во время сборки метаданные будут сгенерированы в файл META-INF/spring-autoconfigure-metadata.properties, который будет выглядеть так:

dev.struchkov.godfather.telegram.starter.config.TelegramBotAutoconfiguration=
dev.struchkov.godfather.telegram.starter.config.TelegramBotAutoconfiguration.AutoConfigureAfter=dev.struchkov.godfather.telegram.starter.config.TelegramBotDataConfiguration
dev.struchkov.godfather.telegram.starter.config.TelegramBotAutoconfiguration.ConditionalOnBean=dev.struchkov.godfather.telegram.simple.core.TelegramConnectBot
dev.struchkov.godfather.telegram.starter.config.TelegramBotDataConfiguration=
dev.struchkov.godfather.telegram.starter.config.TelegramBotDataConfiguration.AutoConfigureAfter=dev.struchkov.godfather.telegram.starter.config.TelegramBotPropertyConfiguration

Использование стартера

Теперь, когда стартер готов, мы можем его добавить в наше другое приложение:

<dependency>
    <groupId>dev.struchkov.godfather.telegram</groupId>
    <artifactId>telegram-bot-spring-boot-starter</artifactId>
    <version>${godfather.telegram.version}</version>
</dependency>

Теперь нам доступны все сконфигурированные бины.

Заключение

Выделить определённые функции в модуль стартер, чтобы использовать их в любом приложении Spring Boot, — дело нескольких простых шагов.

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

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

Для этого имеются всевозможные starter-ы — специальные Maven/Gradle зависимости, которые необходимо только подключить в проект.

Например, подключив в проект всего одну зависимость:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>

мы имеем уже созданный в контексте DataSource, созданный по свойствам в application.properties и другими классами, вроде NamedParameterJdbcTemplate.

Подобные starter основаны на двух специальных функциональностях Spring Boot — AutoConfigurations и Conditional. Покажем, как использовать данные функциональности на примере создания собственного Spring Boot Starter.

Для начала представим, что мы работаем в компании “Марсианская Почта” (com.martianpost). В нашей компании написано множество приложений, для простоты, ровно два — консольное app-example и веб-приложение web-app-example.

Создадим эти приложения с помощью Spring Initializr.

Исходные коды их можно найти вот здесь.

Т. к. мы “Марсианская Почта”, то нам очень важно в каждом приложении знать точное марсианское время (а точнее MSD — Mars Sol Date) для всех приложений.

Выпустим Spring Boot Starter, решающий эту задачу. В соответствии с документацией выдадим следующие Maven-координаты:

    <project ...>
        <groupId>com.martianpost</groupId>
        <artifactId>martian-time-spring-boot-starter</artifactId>
        <version>1.0.0</version>

        ...
    </project>

Для больших проектов и технологий, можно вынести отдельно, как саму технологию — martian-time, так и автоконфигурацию — martian-time-autoconfigure и сам стартер — martian-time-spring-boot-starter. Но для педагогических целей мы просто всё напишем в starter-е.

Из зависимостей мы оставим нам необходим только spring-boot-starter, правда, добавим его с optional-параметром — наш starter не является starter-ом уровнем всего приложения (как, например, spring-boot-starter-web), поэтому spring-boot-starter starter уже будет добавлен в приложение.

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
        <optional>true</optional>
    </dependency>

Ну и реализуем наш сервис:

    package com.martianpost.martiantime.service;

    import org.springframework.stereotype.Service;

    import java.time.Duration;
    import java.time.ZonedDateTime;

    @Service
    public class MartianTimeService {

        private static final ZonedDateTime MID_DAY
            = ZonedDateTime.parse("2000-01-06T00:00:00Z");

        public double toMarsSolDate(ZonedDateTime zonedDateTime) {
            double secondsFromMidDay
                = (double) Duration.between(MID_DAY, zonedDateTime).getSeconds();
            return secondsFromMidDay / 88775.244 + 44795.9998;
        }
    }

Не забудем про тест:

    package com.martianpost.martiantime.service;

    ...

    @DisplayName("Сервис MartianTimeService")
    class MartianTimeServiceTest {

        private final MartianTimeService service = new MartianTimeService();

        @DisplayName("должен конвертировать совпадение полночей в 06.01.2000")
        @Test
        void shouldConvertZeroDay() {
            ZonedDateTime zeroDayUtc = ZonedDateTime.parse("2000-01-06T00:00:00Z");
            double result = service.toMarsSolDate(zeroDayUtc);
            assertEquals(44_795.9998, result, 1e-3);
        }

        @DisplayName("Должен конвертировать пример с http://jtauber.github.io/mars-clock/")
        @Test
        void shouldConvertExampleFromGithub() {
            ZonedDateTime time = ZonedDateTime.parse("2020-05-01T09:44:43Z");
            double result = service.toMarsSolDate(time);
            assertEquals(52_018.84093, result, 1e-3);
        }
    }

Обратим внимание, что если мы подключим данную библиотеку, то сервис не создастcя автоматически (хотя аннотация @Service) — для этого как раз и нужны автоконфигурации.

Создадим автоконфигурацию для нашего модуля:

    package com.martianpost.martiantime;

    ...

    @Configuration
    @ComponentScan
    public class MartianTimeAutoConfiguration {
    }

Данный класс ничем не отличается от обычного класса конфигурации. Его главная задача — найти класс, помеченный @Service и создать его бин.

Но кто найдёт этот класс автоконфигурации? Никто, и нужно дополнительно указать эту автоконфигурацию, чтобы Spring Boot нашёл её:

    # resources/META_INF/spring.factories
    org.springframework.boot.autoconfigure.EnableAutoConfiguration=
    com.martianpost.martiantime.MartianTimeAutoConfiguration

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

    <dependency>
        <groupId>com.martianpost</groupId>
        <artifactId>martian-time-spring-boot-starter</artifactId>
        <version>1.0.0</version>
    </dependency>

и больше ничего!

    @Autowired
    private MartianTimeService martianTimeService;

    @PostConstruct
    public void printCurrentTime() {
        double currentMarsSolDate = martianTimeService.toMarsSolDate(ZonedDateTime.now());
        System.out.println("MSD: " + currentMarsSolDate);
    }

И получаем:


Допустим, нам в каждом веб-приложении необходимо сделать, чтобы это время возвращалось RestController-ом. Но проблема в том, что наш стартер может использоваться как в консольных приложениях, так и в веб-приложениях.

ОК, мы это можем сделать с помощью @Conditional. Сначала изменим зависимости нашего starter-а:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <optional>true</optional>
    </dependency>

Добавим контроллер, который будет создаваться только в веб-приложениях:

    package com.martianpost.martiantime.rest;

    ...
    import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;

    @ConditionalOnWebApplication
    @RestController
    public class MartianTimeController {

        private final MartianTimeService martianTimeService;

        public MartianTimeController(MartianTimeService martianTimeService) {
            this.martianTimeService = martianTimeService;
        }

        @GetMapping("/mds/current")
        public double getMds() {
            return martianTimeService.toMarsSolDate(ZonedDateTime.now());
        }
    }

Обратите внимание, что за магию включения/выключения бина отвечает аннотация @ConditionalOnWebApplication. Помимо неё существует множество других @Conditional аннотаций — ссылка.

Проверим, что наше консольное приложение работает:


Если вывести список зависимостей консольного приложения, то увидим, что spring-mvc там и не присутствует.

А вот подключив в веб-приложение:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>com.martianpost</groupId>
        <artifactId>martian-time-spring-boot-starter</artifactId>
        <version>1.0.0</version>
    </dependency>

И запустив, мы получим:

    GET http://localhost:8080/msd/current
    52018.90259483771

Магия :-) Но доступная каждому :-)

Целиком пример Вы можете посмотреть на GitHub.

Создание собственного стартера с Spring Boot

1. обзор

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

We can also write our own custom starters. Если у нас есть внутренняя библиотека для использования в нашей организации, было бы неплохо также написать для нее стартер, если он будет использоваться в контексте Spring Boot.

Это позволяет разработчикам избежать длительной настройки и быстро начать разработку. Однако из-за множества вещей, происходящих в фоновом режиме, иногда становится трудно понять, как аннотация или просто включение зависимости вpom.xml позволяет использовать такое количество функций.

В этой статье мы демистифицируем магию Spring Boot, чтобы увидеть, что происходит за кулисами. Затем мы будем использовать эти концепции, чтобы создать стартовую страницу для нашей собственной пользовательской библиотеки.

2. Демистификация автоконфигурации Spring Boot

2.1. Классы автоматической конфигурации

Когда Spring Boot запускается, он ищет файл с именемspring.factories в пути к классам. Этот файл находится в каталогеMETA-INF. Давайте посмотрим на фрагмент этого проектаfile from the spring-boot-autoconfigure:

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration

Этот файл отображает имя в разные классы конфигурации, которые Spring Boot попытается запустить. Итак, согласно этому фрагменту, Spring Boot попытается запустить все классы конфигурации для RabbitMQ, Cassandra, MongoDB и Hibernate.

Будут ли эти классы работать на самом деле, будет зависеть от наличия зависимых классов на пути к классам. Например, если классы для MongoDB находятся в пути к классам, будет запущенMongoAutoConfiguration, и будут инициализированы все компоненты, связанные с mongo.

Эта условная инициализация разрешена аннотацией@ConditionalOnClass. Давайте посмотрим на фрагмент кода из классаMongoAutoConfiguration, чтобы увидеть его использование:

@Configuration
@ConditionalOnClass(MongoClient.class)
@EnableConfigurationProperties(MongoProperties.class)
@ConditionalOnMissingBean(type = "org.springframework.data.mongodb.MongoDbFactory")
public class MongoAutoConfiguration {
    // configuration code
}

Теперь, как — еслиMongoClient доступен в пути к классам — этот класс конфигурации запустит заполнение фабрики компонентов Spring с помощьюMongoClient, инициализированного с настройками конфигурации по умолчанию.

2.2. Настраиваемые свойства из файлаapplication.properties

Spring Boot инициализирует компоненты, используя некоторые предварительно настроенные значения по умолчанию. Чтобы переопределить эти значения по умолчанию, мы обычно объявляем их в файлеapplication.properties с определенным именем. Эти свойства автоматически выбираются контейнером Spring Boot.

Давайте посмотрим, как это работает.

В фрагменте кода дляMongoAutoConfiguration аннотация@EnableConfigurationProperties объявляется с классомMongoProperties, который действует как контейнер для настраиваемых свойств:

@ConfigurationProperties(prefix = "spring.data.mongodb")
public class MongoProperties {

    private String host;

    // other fields with standard getters and setters
}

Префикс плюс имя поля составляют имена свойств в файлеapplication.properties. Итак, чтобы установитьhost для MongoDB, нам нужно только написать следующее в файле свойств:

spring.data.mongodb.host = localhost

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

3. Создание пользовательского стартера

Исходя из концепций, приведенных в разделе 2, чтобы создать собственный стартер, нам нужно написать следующие компоненты:

  1. Класс автоматической настройки для нашей библиотеки вместе с классом свойств для пользовательской конфигурации.

  2. Стартовыйpom для ввода зависимостей библиотеки и проекта автоконфигурации.

Для демонстрации мы создалиsimple greeting library, который будет принимать приветственное сообщение для разного времени дня в качестве параметров конфигурации и выводить приветственное сообщение. Мы также создадим пример приложения Spring Boot, чтобы продемонстрировать использование наших модулей автоконфигурирования и запуска.

3.1. Модуль автоконфигурации

Назовем наш модуль автоматической настройкиgreeter-spring-boot-autoconfigure. Этот модуль будет иметь два основных класса, т.е. GreeterProperties, который позволит установить пользовательские свойства через файлapplication.properties иGreeterAutoConfiguartion, который создаст bean-компоненты для библиотекиgreeter.

Давайте посмотрим на код обоих классов:

@ConfigurationProperties(prefix = "example.greeter")
public class GreeterProperties {

    private String userName;
    private String morningMessage;
    private String afternoonMessage;
    private String eveningMessage;
    private String nightMessage;

    // standard getters and setters

}
@Configuration
@ConditionalOnClass(Greeter.class)
@EnableConfigurationProperties(GreeterProperties.class)
public class GreeterAutoConfiguration {

    @Autowired
    private GreeterProperties greeterProperties;

    @Bean
    @ConditionalOnMissingBean
    public GreetingConfig greeterConfig() {

        String userName = greeterProperties.getUserName() == null
          ? System.getProperty("user.name")
          : greeterProperties.getUserName();

        // ..

        GreetingConfig greetingConfig = new GreetingConfig();
        greetingConfig.put(USER_NAME, userName);
        // ...
        return greetingConfig;
    }

    @Bean
    @ConditionalOnMissingBean
    public Greeter greeter(GreetingConfig greetingConfig) {
        return new Greeter(greetingConfig);
    }
}

Нам также необходимо добавить файлspring.factories в каталогsrc/main/resources/META-INF со следующим содержимым:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=
  com.example.greeter.autoconfigure.GreeterAutoConfiguration

При запуске приложения классGreeterAutoConfiguration будет запущен, если классGreeter присутствует в пути к классам. В случае успешного запуска он заполнит контекст приложения Spring компонентамиGreeterConfig иGreeter, прочитав свойства через классGreeterProperties.

Аннотация@ConditionalOnMissingBean гарантирует, что эти bean-компоненты будут созданы, только если они еще не существуют. Это позволяет разработчикам полностью переопределять автоматически настраиваемые bean-компоненты, определяя свои собственные в одном из классов@Configuration.

3.2. Созданиеpom.xml

Теперь давайте создадим начальныйpom, который внесет зависимости для модуля автоматической настройки и библиотеки приветствия.

В соответствии с соглашением об именах все стартеры, которые не управляются основной командой Spring Boot, должны начинаться с имени библиотеки, за которым следует суффикс-spring-boot-starter. Поэтому мы будем называть наш стартерgreeter-spring-boot-starter:


    4.0.0

    com.example
    greeter-spring-boot-starter
    0.0.1-SNAPSHOT

    
        UTF-8
        0.0.1-SNAPSHOT
        1.5.2.RELEASE
    

    

        
            org.springframework.boot
            spring-boot-starter
            ${spring-boot.version}
        

        
            com.example
            greeter-spring-boot-autoconfigure
            ${project.version}
        

        
            com.example
            greeter
            ${greeter.version}
        

    

3.3. Использование стартера

Давайте создадимgreeter-spring-boot-sample-app, который будет использовать стартер. Вpom.xml нам нужно добавить его как зависимость:


    com.example
    greeter-spring-boot-starter
    ${greeter-starter.version}

Spring Boot автоматически настроит все, и у нас будет bean-компонентGreeter, готовый к внедрению и использованию.

Давайте также изменим некоторые значения по умолчанию дляGreeterProperties, определив их в файлеapplication.properties с префиксомexample.greeter:

example.greeter.userName=example
example.greeter.afternoonMessage=Woha Afternoon

Наконец, давайте использовать bean-компонентGreeter в нашем приложении:

@SpringBootApplication
public class GreeterSampleApplication implements CommandLineRunner {

    @Autowired
    private Greeter greeter;

    public static void main(String[] args) {
        SpringApplication.run(GreeterSampleApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        String message = greeter.greet();
        System.out.println(message);
    }
}

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

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

Полный исходный код всех модулей, которые мы создали в этой статье, можно найти вover on GitHub.

Полная версия Spring Boot для библиотеки может содержать следующие компоненты:

  • Модуль autoconfigure, который содержит код автоконфигурации.
  • Модуль starter, который обеспечивает зависимость для модуля автоматической настройки, а также библиотеки и любые дополнительные зависимости, которые обычно полезны. Короче говоря, добавление стартера должно обеспечить все необходимое для начала использования этой библиотеки.

Вы можете объединить код автоконфигурации и управление зависимостями в одном модуле, если вам не нужно разделять эти две проблемы.

Именование

Вы должны убедиться, что предоставили правильное пространство имен для своего стартера. Не начинайте имена модулей со spring-boot, даже если вы используете другой Maven groupId. В будущем возможна официальная поддержка для вещи, которую вы автоматически настраиваете.

Как правило, вы должны назвать комбинированный модуль как стартер. Например, предположим, что вы создаете стартер для «acme» назовите модуль автоконфигурации acme-spring-boot-autoconfigure, а стартер acme-spring-boot-starter. Если у вас есть только один модуль, который объединяет оба, назовите его acme-spring-boot-starter.

Конфигурационные ключи

Если ваш стартер предоставляет конфигурационные ключи, используйте для них уникальное пространство имен. В частности, не включайте ваши ключи в пространства имен, которые использует Spring Boot (например, server, management, spring и т. д.). Если вы используете пространства имен Spring Boot, возможно изменение этих пространств имен в будущем таким образом, что это будет нарушать работу ваших модулей. Как правило, перед всеми вашими ключами добавьте пространство имен, которым вы владеете (например, acme).

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

@ConfigurationProperties("acme")
public class AcmeProperties {

    /**
     * Нужно ли проверять расположение ресурсов acme.
     */
    private boolean checkLocation = true;

    /**
     * Таймаут для установления соединения с сервером acme.
     */
    private Duration loginTimeout = Duration.ofSeconds(3);

    // getters & setters

}

Вы должны использовать только простой текст с полем @ConfigurationProperties Javadoc, поскольку они не обрабатываются перед добавлением в JSON.

Вот некоторые правила, которым следуют в Spring, чтобы убедиться, что описания соответствуют:

  • Не начинайте описание с «The» или «A» (артиклей в английском языке, при описании на английском).
  • Для логических типов начните описание с «Whether» или «Enable».
  • Для основанных на коллекции типов, начните описание с «Comma-separated list»
  • Используйте java.time.Duration вместо long и опишите модуль по умолчанию, если он отличается от миллисекунд, например «Если суффикс продолжительности не указан, будут использованы секунды».
  • Не указывайте значение по умолчанию в описании, если оно не должно быть определено во время выполнения.

Обязательно запустите генерацию метаданных, чтобы помощь IDE была доступна и для ваших ключей. Вы можете просмотреть сгенерированные метаданные (META-INF/spring-configuration-metadata.json), чтобы убедиться, что ваши ключи правильно документированы. Использование собственного стартера в совместимой IDE также является хорошей идеей для проверки качества метаданных.

Модуль autoconfigure

Модуль autoconfigure содержит все необходимое для начала работы с библиотекой. Он также может содержать определения ключей конфигурации (например, @ConfigurationProperties) и любой интерфейс обратного вызова, который можно использовать для дальнейшей настройки инициализации компонентов.

Вы должны пометить зависимости от библиотеки как optional, чтобы вы могли легче включить модуль autoconfigure в свои проекты.

Spring Boot использует процессор аннотаций для сбора условий автоконфигурирования в файле метаданных (META-INF/spring-autoconfigure-metadata.properties). Если этот файл присутствует, он используется для активной фильтрации автоконфигураций, которые не совпадают, что улучшит время запуска. Рекомендуется добавить следующую зависимость в модуль, который содержит автоконфигурации:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-autoconfigure-processor</artifactId>
    <optional>true</optional>
</dependency>

В Gradle 4.5 и более ранних версиях зависимость должна быть объявлена ​​в конфигурации compileOnly, как показано в следующем примере:

dependencies {
    compileOnly "org.springframework.boot:spring-boot-autoconfigure-processor"
}

В Gradle 4.6 и более поздних версиях зависимость должна быть объявлена ​​в конфигурации annotationProcessor, как показано в следующем примере:

dependencies {
    annotationProcessor "org.springframework.boot:spring-boot-autoconfigure-processor"
}

Модуль Starter

Стартер на самом деле пустой jar. Его единственная цель — предоставить необходимые зависимости для работы с библиотекой. Вы можете думать об этом как о рекомендуемом взгляде на то, что требуется, чтобы начать.

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

В любом случае, ваш стартер должен прямо или косвенно ссылаться на основной стартер Spring Boot (spring-boot-starter) (то есть нет необходимости добавлять его, если ваш стартер использует другой стартер). Если проект создается только с вашим пользовательским стартером, основные функции Spring Boot будут учитываться наличием основного стартера.


Читайте также:

  • Spring Boot: создание собственной автоконфигурации
  • Spring Boot: создание собственной автоконфигурации, аннотации условий
  • Spring Boot: создание собственной автоконфигурации, тестирование собственной автоконфигурации

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

1. Обзор

Разработчики core Spring Boot предоставляют стартеры для большинства популярных проектов с открытым исходным кодом, но мы не ограничиваемся ими.

Мы также можем написать ваши собственные стартеры . Если у нас есть внутренняя библиотека для использования в нашей организации, было бы хорошей практикой также написать для нее стартер, если она будет использоваться в контексте весенней загрузки.

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

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

2.1. Классы автоматической настройки

При запуске Spring Boot он ищет файл с именем spring.factories в пути к классу. Этот файл находится в каталоге META-INF . Давайте посмотрим на фрагмент этого файла из проекта spring-boot-autoconfigure :

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration

Этот файл сопоставляет имя с различными классами конфигурации, которые попытается запустить Spring Boot. Итак, согласно этому фрагменту, Spring Boot попытается запустить все классы конфигурации для RabbitMQ, Cassandra, MongoDB и Hibernate.

Будут ли эти классы фактически выполняться, будет зависеть от наличия зависимых классов в пути к классам. Например, если классы для MongoDB находятся на пути к классам, mongautoconfiguration будет запущен, и все связанные с mongo компоненты будут инициализированы.

Эта условная инициализация включена аннотацией @ConditionalOnClass . Давайте посмотрим на фрагмент кода из mongautoconfiguration class, чтобы увидеть его использование:

@Configuration
@ConditionalOnClass(MongoClient.class)
@EnableConfigurationProperties(MongoProperties.class)
@ConditionalOnMissingBean(type = "org.springframework.data.mongodb.MongoDbFactory")
public class MongoAutoConfiguration {
    // configuration code
}

Теперь, как – если MongoClient доступен в пути к классу – этот класс конфигурации будет работать, заполняя фабрику Spring bean с MongoClient , инициализированной настройками конфигурации по умолчанию.

2.2. Пользовательские свойства из файла application.properties

Spring Boot инициализирует компоненты, используя некоторые предварительно настроенные значения по умолчанию. Чтобы переопределить эти значения по умолчанию, мы обычно объявляем их в файле application.properties с определенным именем. Эти свойства автоматически подхватываются загрузочным контейнером Spring.

Давайте посмотрим, как это работает.

В фрагменте кода для mongautoconfiguration , @EnableConfigurationProperties аннотация объявляется с классом MongoProperties , который действует как контейнер для пользовательских свойств:

@ConfigurationProperties(prefix = "spring.data.mongodb")
public class MongoProperties {

    private String host;

    // other fields with standard getters and setters
}

Префикс плюс имя поля составляют имена свойств в файле application.properties . Итак, чтобы установить host для MongoDB, нам нужно только написать следующее в файле свойств:

spring.data.mongodb.host = localhost

Аналогично, значения для других полей в классе можно задать с помощью файла свойств.

3. Создание пользовательского стартера

Основываясь на концепциях, приведенных в разделе 2, для создания пользовательского стартера нам необходимо написать следующие компоненты:

  1. Класс автоматической настройки для нашей библиотеки вместе с классом свойств для пользовательской конфигурации.
  2. Стартер pot для включения зависимостей библиотеки и проекта автоматической настройки.

Для демонстрации мы создали простую библиотеку приветствий , которая будет принимать поздравительное сообщение в разное время суток в качестве параметров конфигурации и выводить поздравительное сообщение. Мы также создадим пример приложения Spring Boot, чтобы продемонстрировать использование наших модулей автоматической настройки и запуска.

3.1. Модуль Автоконфигурации

Мы назовем наш модуль автоматической настройки greeter-spring-boot-autoconfigure . Этот модуль будет иметь два основных класса, т. е. Большие свойства , которые позволят устанавливать пользовательские свойства через application.properties file и GreeterAutoConfiguartion , которые создадут компоненты для greeter library.

Давайте посмотрим на код для обоих классов:

@ConfigurationProperties(prefix = "baeldung.greeter")
public class GreeterProperties {

    private String userName;
    private String morningMessage;
    private String afternoonMessage;
    private String eveningMessage;
    private String nightMessage;

    // standard getters and setters

}
@Configuration
@ConditionalOnClass(Greeter.class)
@EnableConfigurationProperties(GreeterProperties.class)
public class GreeterAutoConfiguration {

    @Autowired
    private GreeterProperties greeterProperties;

    @Bean
    @ConditionalOnMissingBean
    public GreetingConfig greeterConfig() {

        String userName = greeterProperties.getUserName() == null
          ? System.getProperty("user.name") 
          : greeterProperties.getUserName();
        
        // ..

        GreetingConfig greetingConfig = new GreetingConfig();
        greetingConfig.put(USER_NAME, userName);
        // ...
        return greetingConfig;
    }

    @Bean
    @ConditionalOnMissingBean
    public Greeter greeter(GreetingConfig greetingConfig) {
        return new Greeter(greetingConfig);
    }
}

Нам также необходимо добавить файл spring.factories в каталог src/main/resources/META-INF со следующим содержимым:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=
  com.baeldung.greeter.autoconfigure.GreeterAutoConfiguration

При запуске приложения класс Greeter Auto Configuration будет запущен, если класс Greeter присутствует в пути к классу. При успешном запуске он заполнит контекст приложения Spring с помощью Greeter Config и Greeter beans, прочитав свойства через GreeterProperties class.

Аннотация @ConditionalOnMissingBean гарантирует, что эти компоненты будут созданы только в том случае, если они еще не существуют. Это позволяет разработчикам полностью переопределить автоматически настроенные компоненты, определив их собственные в одном из классов @Configuration .

3.2. Создание pom.xml

Теперь давайте создадим starter pom , который введет зависимости для модуля автоматической настройки и библиотеки приветствия.

Согласно соглашению об именовании, все стартеры, которые не управляются основной командой загрузки Spring, должны начинаться с имени библиотеки, за которым следует суффикс -spring-boot-starter . Поэтому мы будем называть наш стартер как greater-spring-boot-starter:

    4.0.0

    com.baeldung
    greeter-spring-boot-starter
    0.0.1-SNAPSHOT

    
        UTF-8
        0.0.1-SNAPSHOT
        2.2.6.RELEASE
    

    

        
            org.springframework.boot
            spring-boot-starter
            ${spring-boot.version}
        

        
            com.baeldung
            greeter-spring-boot-autoconfigure
            ${project.version}
        

        
            com.baeldung
            greeter
            ${greeter.version}
        

    

3.3. Использование стартера

Давайте создадим greater-spring-boot-sample-app , который будет использовать стартер. В pom.xml нам нужно добавить его в качестве зависимости:

    com.baeldung
    greeter-spring-boot-starter
    ${greeter-starter.version}

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

Давайте также изменим некоторые значения по умолчанию для Больших свойств , определив их в файле application.properties с префиксом baeldung.greeter :

baeldung.greeter.userName=Baeldung
baeldung.greeter.afternoonMessage=Woha Afternoon

Наконец, давайте использовать Greater bean в нашем приложении:

@SpringBootApplication
public class GreeterSampleApplication implements CommandLineRunner {

    @Autowired
    private Greeter greeter;

    public static void main(String[] args) {
        SpringApplication.run(GreeterSampleApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        String message = greeter.greet();
        System.out.println(message);
    }
}

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

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

Полный исходный код для всех модулей, которые мы создали в этой статье, можно найти на GitHub .

Before Spring Boot was introduced, Spring Developers used to spend a lot of time on Dependency management. Spring Boot Starters were introduced to solve this problem so that the developers can spend more time on actual code than Dependencies. Spring Boot Starters are dependency descriptors that can be added under the <dependencies> section in pom.xml. There are around 50+ Spring Boot Starters for different Spring and related technologies. These starters give all the dependencies under a single name. For example, if you want to use Spring Data JPA for database access, you can include spring-boot-starter-data-jpa dependency. 

The advantages of using Starters are as follows:

  • Increase productivity by decreasing the Configuration time for developers.
  • Managing the POM is easier since the number of dependencies to be added is decreased.
  • Tested, Production-ready, and supported dependency configurations.
  • No need to remember the name and version of the dependencies.

Spring Boot Starter Data JPA is illustrated below: 

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
</dependencies>

This gives all the required dependencies and can be seen under the Maven tab in IntelliJ IDEA.

Spring Boot Data JPA dependencies

In earlier days, developers used to include all those dependencies. Now Spring Boot Starters provides all those with just a single dependency. The official starters follow a naming convention spring-boot-starter-*, where * denotes application type. For example, if we want to build web including RESTful applications using Spring MVC we have to use spring-boot-starter-web dependency.

Third-Party Starters

If you want to make your own starter or other third-party starters name should not start with spring-boot as it reserved for official Spring Boot Starters. It can start with the name of the project. For example, if the name of the project is gfg-code-template, then the name of the starter can be gfg-code-template-spring-boot-starter

Here out we will be discussing all 3 starters and the following starters are provided by the Spring Boot under org.springframework.boot group. They are namely and covered as follows:

  1. Application Starters
  2. Production Starters
  3. Technical Starters 

Let us elaborate these starters in the same sequential order which is as follows:

(A) Spring Boot Application Starters

Name 

Description

spring-boot-starter Core starter, including auto-configuration support, logging, and YAML
spring-boot-starter-activemq Starter for JMS messaging using Apache ActiveMQ
spring-boot-starter-amqp Starter for using Spring AMQP and Rabbit MQ
spring-boot-starter-aop Starter for aspect-oriented programming with Spring AOP and AspectJ
spring-boot-starter-artemis Starter for JMS messaging using Apache Artemis
spring-boot-starter-batch Starter for using Spring Batch
spring-boot-starter-cache Starter for using Spring Framework’s caching support
spring-boot-starter-data-cassandra Starter for using Cassandra distributed database and Spring Data Cassandra
spring-boot-starter-data-cassandra-reactive Starter for using Cassandra distributed database and Spring Data Cassandra Reactive
spring-boot-starter-data-couchbase Starter for using Couchbase document-oriented database and Spring Data Couchbase
spring-boot-starter-data-couchbase-reactive Starter for using Couchbase document-oriented database and Spring Data Couchbase Reactive
spring-boot-starter-data-elasticsearch Starter for using Elasticsearch search and analytics engine and Spring Data Elasticsearch
spring-boot-starter-data-jdbc Starter for using Spring Data JDBC
spring-boot-starter-data-jpa Starter for using Spring Data JPA with Hibernate
spring-boot-starter-data-ldap Starter for using Spring Data LDAP
spring-boot-starter-data-mongodb Starter for using MongoDB document-oriented database and Spring Data MongoDB
spring-boot-starter-data-mongodb-reactive Starter for using MongoDB document-oriented database and Spring Data MongoDB Reactive
spring-boot-starter-data-neo4j Starter for using Neo4j graph database and Spring Data Neo4j
spring-boot-starter-data-r2dbc Starter for using Spring Data R2DBC
spring-boot-starter-data-redis Starter for using Redis key-value data store with Spring Data Redis and the Lettuce client
spring-boot-starter-data-redis-reactive Starter for using Redis key-value data store with Spring Data Redis reactive and the Lettuce client
spring-boot-starter-data-rest Starter for exposing Spring Data repositories over REST using Spring Data REST
spring-boot-starter-freemarker Starter for building MVC web applications using FreeMarker views
spring-boot-starter-groovy-templates Starter for building MVC web applications using Groovy Templates views
spring-boot-starter-hateoas Starter for building hypermedia-based RESTful web application with Spring MVC and Spring HATEOAS
spring-boot-starter-integration Starter for using Spring Integration
spring-boot-starter-jdbc Starter for using JDBC with the HikariCP connection pool
spring-boot-starter-jersey Starter for building RESTful web applications using JAX-RS and Jersey. An alternative to spring-boot-starter-web
spring-boot-starter-jooq Starter for using jOOQ to access SQL databases. An alternative to spring-boot-starter-data-jpa or spring-boot-starter-jdbc
spring-boot-starter-json Starter for reading and writing json
spring-boot-starter-jta-atomikos Starter for JTA transactions using Atomikos
spring-boot-starter-mail Starter for using Java Mail and Spring Framework’s email sending support
spring-boot-starter-mustache Starter for building web applications using Mustache views
spring-boot-starter-oauth2-client Starter for using Spring Security’s OAuth2/OpenID Connect client features
spring-boot-starter-oauth2-resource-server Starter for using Spring Security’s OAuth2 resource server features
spring-boot-starter-quartz Starter for using the Quartz scheduler
spring-boot-starter-rsocket Starter for building RSocket clients and servers
spring-boot-starter-security Starter for using Spring Security
spring-boot-starter-test Starter for testing Spring Boot applications with libraries including JUnit Jupiter, Hamcrest and Mockito
spring-boot-starter-thymeleaf Starter for building MVC web applications using Thymeleaf views
spring-boot-starter-validation Starter for using Java Bean Validation with Hibernate Validator
spring-boot-starter-web Starter for building web, including RESTful, applications using Spring MVC. Uses Tomcat as the default embedded container.
spring-boot-starter-web-services Starter for using Spring Web Services
spring-boot-starter-webflux Starter for building WebFlux applications using Spring Framework’s Reactive Web support
spring-boot-starter-websocket Starter for building WebSocket applications using Spring Framework’s WebSocket support

(B) Spring Boot Production Starters

Name

Description

spring-boot-starter-actuator Starter for using Spring Boot’s Actuator which provides production-ready features to help you monitor and manage your application

(C) Spring Boot Technical Starters

Name

Description

spring-boot-starter-jetty Starter for using Jetty as the embedded servlet container. An alternative to spring-boot-starter-tomcat
spring-boot-starter-log4j2 Starter for using Log4j2 for logging. An alternative to spring-boot-starter-logging
spring-boot-starter-logging Starter for logging using Logback. Default logging starter
spring-boot-starter-reactor-netty Starter for using Reactor Netty as the embedded reactive HTTP server.
spring-boot-starter-tomcat Starter for using Tomcat as the embedded servlet container. Default servlet container starter used by spring-boot-starter-web
spring-boot-starter-undertow Starter for using Undertow as the embedded servlet container. An alternative to spring-boot-starter-tomcat

Понравилась статья? Поделить с друзьями:
  • Как написать свой плагин для майнкрафт
  • Как написать свой социальный статус
  • Как написать свой плагин для minecraft
  • Как написать свой плагин для joomla
  • Как написать свой парсер сайтов