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

Создание собственного стартера с 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.