Spring Boot(1): основные аннотации — загрузка и настройка компонентов

Spring Boot

1. @SpringBootApplication

Эта аннотация на самом деле является аббревиатурой для следующих трех аннотаций:

  • @EnableAutoConfiguration
  • @ComponentScan
  • @SpringBootConfiguration

он используется для обозначенияmainКласс, в котором находится метод:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
 
@SpringBootApplication
public class Application {
 
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
 
}

2. @EnableAutoConfiguration

Эта аннотация включает глобальную автоматическую настройку.После маркировки этой аннотации Spring Boot обработает следующий пакет jar.META-INF/spring.factoriesфайл, содержимое этого файла может быть следующим:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.mycorp.libx.autoconfigure.LibXAutoConfiguration,\
com.mycorp.libx.autoconfigure.LibXWebAutoConfiguration

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

3. @SpringBootConfiguration

Эта аннотация связана с@ConfigurationЭффект аннотации такой же, он используется для обозначения класса как класса конфигурации Spring Boot.

В-четвертых, @EnableAutoConfiguration

Если мы не хотим использовать@EnableAutoConfigurationВключите глобальную автоматическую настройку, иногда мы хотим использовать только часть конфигурации, а затем использовать аннотации.@ImportAutoConfigurationДанный класс конфигурации можно импортировать:

@ComponentScan("path.to.your.controllers")
@ImportAutoConfiguration({WebMvcAutoConfiguration.class
    ,DispatcherServletAutoConfiguration.class
    ,EmbeddedServletContainerAutoConfiguration.class
    ,ServerPropertiesAutoConfiguration.class
    ,HttpMessageConvertersAutoConfiguration.class})
public class App 
{
    public static void main(String[] args) 
    {
        SpringApplication.run(App.class, args);
    }
}

5. Укажите порядок загрузки конфигурации

Если наша конфигурация должна зависеть от других конфигураций, то для указания порядка загрузки конфигурации можно использовать следующие три аннотации:

  • @AutoConfigureBefore, указывающий, что загрузка выполняется перед загрузкой bean-компонента;
  • @AutoConfigureAfter, указывающий, что бин загружается после загрузки;
  • @AutoConfigureOrder, эта аннотация может принимать целое число, чтобы явно указать порядок загрузки, который совпадает с@Orderимеют одинаковую семантику.

Пример: использование @AutoConfigureAfter

@Configuration
@AutoConfigureAfter(CacheAutoConfiguration.class)
@ConditionalOnBean(CacheManager.class)
@ConditionalOnClass(CacheStatisticsProvider.class)
public class RedissonCacheStatisticsAutoConfiguration 
{
    @Bean
    public RedissonCacheStatisticsProvider redissonCacheStatisticsProvider(){
        return new RedissonCacheStatisticsProvider();
    }
}

В приведенном выше коде только послеCacheAutoConfigurationне будет загружен, пока загрузка не будет завершенаRedissonCacheStatisticsAutoConfiguration.

6. Условная загрузка и конфигурация бина

Функция автоматической настройки Spring Boot в основном загружается путем загрузки@ConfigurationАннотированный класс конфигурации для реализации. Чтобы обеспечить более высокую масштабируемость, Spring Boot предоставляет ряд@ConditionalАннотация используется для ограничения времени загрузки конфигурации.

6.1 Загрузка конфигурации на основе существования Bean-компонента

  • @ConditionalOnBean, когда указанный bean-компонент существует в контейнере Spring, загружается соответствующая конфигурация;
  • @ConditionalOnMissingBean, когда указанный bean-компонент не существует в контейнере Spring, загружается соответствующая конфигурация.

Они могут принимать имя компонента илиClassкак параметр.

Пример: использование @ConditionalOnMissingBean

@Configuration
public class MyAutoConfiguration {
    @Bean
    @ConditionalOnMissingBean
    public MyService myService() { ... }
}

В приведенном выше коде, когда контейнер Spring не существуетMyServiceОн будет введен только тогда, когда используется bean-компонент типа.

6.2 Конфигурация нагрузки в зависимости от наличия класса

  • @ConditionalOnClass, соответствующая конфигурация загружается только тогда, когда указанный класс существует;
  • @ConditionalMissingClass, соответствующая конфигурация загружается только тогда, когда указанный класс не существует.

они могут принятьClassИли путь к классам типа string в качестве параметра.

Пример: использование @ConditionalOnClass

@Configuration
// Some conditions
public class MyAutoConfiguration {

    // Auto-configured beans

    @Configuration
    @ConditionalOnClass(EmbeddedAcmeService.class)
    static class EmbeddedConfiguration {

        @Bean
        @ConditionalOnMissingBean
        public EmbeddedAcmeService embeddedAcmeService() { ... }

    }

}

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

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

Однако JVM выдаст исключение ClassNotFoundException, если одновременно возникнут следующие три условия:

  • @Bean,@ConditionalOnClassили@ConditionalMissingClassАннотировано по тому же методу;
  • @BeanТип возвращаемого значения аннотированного метода такой же, как@ConditionalOnClassили@ConditionalMissingClassЭтот же тип указан в аннотации;
  • Во время выполнения этот типclasspathне существует в .

6.3 Загрузить конфигурацию в зависимости от того, является ли она веб-приложением или нет

  • @ConditionalOnNotWebApplication, соответствующая конфигурация будет загружена только тогда, когда текущее приложение не является веб-приложением;
  • @ConditionalOnWebApplication, соответствующая конфигурация будет загружена только в том случае, если текущее приложение является веб-приложением.

Spring Boot определяет, что приложение является веб-приложением, и требует выполнения хотя бы одного из следующих трех условий:

  • Используемый контекстWebApplicationContext;
  • Есть боб сsessionобъем;
  • существуетStandardServletEnvironment.

6.4 Загрузить конфигурацию в соответствии со свойством

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

Пример: использовать@ConditionalOnProperty

@Configuration
public class DataSourceConfiguration {
    @Bean
    @ConditionalOnProperty(name = "env", havingValue = "local")
    DataSource localDataSource() 
    {
        // ...
    }
    
    @Bean
    @ConditionalOnProperty(name = "env", havingValue = "prod")
    DataSource prodDataSource() 
    {
        // ...
    }
}

Приведенный выше код демонстрирует динамическую загрузку DataSource, которая пройдет проверкуapplication.propertiesв файлеenvЗначение параметра динамически загружает источник данных в контейнер Spring.

6.5 Загрузка конфигурации на основе наличия ресурсов

аннотация@ConditionalOnResourceСоответствующая конфигурация может быть загружена в зависимости от того, существует ли указанный ресурс.

Пример: использовать@ConditionalOnResource

@Configuration
public class VendorConfiguration {
    @ConditionalOnResource(resources = "classpath:vendor.properties")
    Properties additionalProperties() 
    {
        // 对vendor.properties进行一些处理
        // ...
    }
}

В приведенном выше коде только тогда, когда файлclasspath:vendor.propertiesОн будет обработан только в том случае, если он существует.

6.6 Загрузка конфигураций на основе выражений SpEL

аннотация@ConditionalOnExpressionРезультат выражения SpEL можно проверить, и соответствующая конфигурация будет загружена, только если выражение оценивается как истинное.

Пример: использовать@ConditionalOnExpressionзаменять@ConditionalOnProperty

@Configuration
public class DataSourceConfiguration {
    @Bean
    @ConditionalOnExpression("${env} && ${havingValue == 'local'}")
    DataSource localDataSource() 
    {
        // ...
    }
    
    @Bean
    @ConditionalOnExpression("${env} && ${havingValue == 'prod'}")
    DataSource prodDataSource() 
    {
        // ...
    }
}

В приведенном выше коде используется@ConditionalOnExpressionзаменены@ConditionalOnProperty, который также может реализовать динамическую загрузку DataSource.

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

аннотация@ConditionalOnCloudPlatformОн может определять облачную платформу, на которой размещено приложение Spring Boot. Когда приложение запускается на указанной облачной платформе, будет загружена соответствующая конфигурация. Эта аннотация поддерживает следующие часто используемые облачные платформы:

  • Cloud Foundry
  • Heroku
  • Kubernetes
  • SAP

Пример: использовать@ConditionalOnCloudPlatform

@Configuration
@ConditionalOnCloudPlatform(CloudPlatform.KUBERNETES)
public class CloudConfigurationExample 
{
  @Bean
  public MyBean myBean(MyProperties properties) 
  {
    return new MyBean(properties.getParam);
  }
}

В приведенном выше коде он будет загружен только тогда, когда наша программа Spring Boot работает на платформе K8S.MyBeanв контейнер Spring.

Кроме того, перечислениеCloudPlatformЕсть четыре значения перечисления в :

  • CLOUD_FOUNDRY
  • HEROKU
  • KUBERNETES
  • SAP

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

Возможности Spring Boot — создание собственной автоматической конфигурации