В аннотации @ConfigurationProperties используется положение, этого достаточно

При написании кода проекта нам требуется более гибкая конфигурация и лучшая модульная интеграция. В проекте Spring Boot, чтобы удовлетворить вышеуказанные требования, мы настраиваем большое количество параметров в файле application.properties или application.yml, через@ConfigurationPropertiesАннотация, мы можем легко получить эти значения параметров

Настройте модули с помощью @ConfigurationProperties

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

Создайте эти параметры в файле application.properties:

мы можем использовать@ValueАннотируйте или используйте SpringEnvironmentБин получает доступ к этим свойствам, что иногда затрудняет внедрение конфигурации. Мы будем использовать более безопасный метод (@ConfigurationProperties), чтобы получить эти свойства

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

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

Правила расслабленной привязки Spring (ослабленная привязка)

Spring использует некоторые свободные правила для связывания свойств. Поэтому все следующие варианты будут привязаны к свойству hostName:

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

Однако нам все еще нужно сообщить Spring, что наш класс @ConfigurationProperties существует, чтобы загрузить его в контекст приложения (Не знаете разницу между BeanFactory и ApplicationContext во время собеседования?)

активировать @ConfigurationProperties

Для Spring Boot создайте bean-компонент типа MailModuleProperties, который мы можем добавить в контекст приложения следующими способами.

Во-первых, мы можем позволить компонентному сканированию сканировать

Очевидно, только если пакет, в котором находится класс, используется Spring@ComponentScanАннотация вступит в силу только после сканирования.По умолчанию аннотация будет сканировать все структуры пакета в основном классе приложения.

Мы также можем добиться того же эффекта с помощью функции Spring Java Configuration:

Пока класс MailModuleConfiguration сканируется приложением Spring Boot, мы можем получить доступ к bean-компоненту MailModuleProperties в контексте приложения.

мы также можем использовать@EnableConfigurationPropertiesАннотации позволяют нашему классу быть известным Spring Boot, в этой аннотации фактически используется@Import(EnableConfigurationPropertiesImportSelector.class)поняла, ты видишь

Как лучше всего активировать класс @ConfigurationProperties?

Все вышеперечисленные способы работают одинаково хорошо. Тем не менее, я рекомендую разбить ваше приложение на модули, чтобы каждый модуль предоставлял свои собственные функции.@ConfigurationPropertiesclass, предоставляя только те свойства, которые ему нужны, как мы сделали с почтовым модулем в приведенном выше коде. Это упрощает рефакторинг свойств в одном модуле, не затрагивая другие модули.

Поэтому я не рекомендую использовать его в самом классе приложения.@EnableConfigurationProperties, как показано во многих других учебниках, используется в классе @Configuration, специфичном для модуля.@EnableConfigurationProperties, который также может использовать видимость для отдельных пакетов, чтобы скрыть свойства от остальной части приложения.

имущество, которое не может быть преобразовано

Что произойдет, если свойства, которые мы определяем в свойстве application.properties, не могут быть правильно разрешены? Предположим, мы предоставляем значение 'foo' для свойства, которое должно быть логическим значением:

По умолчанию Spring Boot не запустится и выдаст исключение:

Failed to bind properties under 'myapp.mail.enabled' to java.lang.Boolean:

    Property: myapp.mail.enabled
    Value: foo
    Origin: class path resource [application.properties]:1:20
    Reason: failed to convert java.lang.String to java.lang.Boolean

Когда мы настраиваем неправильное значение для свойства и не хотим, чтобы приложение Spring Boot не запускалось, мы можем установитьignoreInvalidFieldsсвойство истинно (по умолчанию ложно)

Таким образом, Spring Boot установит для поля enable значение по умолчанию, которое мы установили в коде Java. Если мы не установим значение по умолчанию, enable будет иметь значение null, потому что здесь есть класс-оболочка для логического логического значения.

неизвестное свойство

Вопреки вышесказанному, что произойдет, если мы предоставим в файле application.properties свойства, о которых класс MailModuleProperties не знает?

По умолчанию Spring Boot игнорирует те, которые не могут быть привязаны к@ConfigurationPropertiesсвойства полей класса

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

Для того, чтобы достичь описанной выше ситуации, нам нужно толькоignoreUnknownFieldsсвойство установлено в false (по умолчанию true)

Теперь при запуске приложения консоль выдаст нам сообщение об исключении

Binding to target [Bindable@cf65451 type = com.example.configurationproperties.properties.MailModuleProperties, value = 'provided', annotations = array<Annotation>[@org.springframework.boot.context.properties.ConfigurationProperties(value=myapp.mail, prefix=myapp.mail, ignoreInvalidFields=false, ignoreUnknownFields=false)]] failed:

    Property: myapp.mail.unknown-property
    Value: foo
    Origin: class path resource [application.properties]:3:29
    Reason: The elements [myapp.mail.unknown-property] were left unbound.

Предупреждение об устаревании ⚠️ (Предупреждение об устаревании)

ignoreUnknownFieldsбудет помечен как устаревший в будущем выпуске Spring Boot, потому что у нас может быть два@ConfigurationPropertiesКлассы привязаны к одному и тому же пространству имен (namespace) одновременно, один из классов может знать определенное свойство, а другой класс не знать определенное свойство, что приведет к сбою запуска

Проверять @ConfigurationProperties при запуске

Если мы хотим, чтобы параметры конфигурации были действительными при передаче в приложение, мы можем сделать это, добавивbean validationАннотация при добавлении в класс@Validatedаннотация

Если мы забудем установить свойство enable в файле application.properties и установить значение defaultSubject пустым

Когда приложение запустится, мы получимBindValidationException

Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'myapp.mail' to com.example.configurationproperties.properties.MailModuleProperties failed:

    Property: myapp.mail.enabled
    Value: null
    Reason: must not be null

    Property: myapp.mail.defaultSubject
    Value: null
    Reason: must not be empty

Конечно, эти аннотации проверки по умолчанию не могут соответствовать вашим требованиям проверки, мы также можем настроить аннотации.

Если ваша логика проверки очень особенная, мы можем реализовать метод и пометить его с помощью @PostConstruct. Если проверка не пройдена, метод может вызвать исключение. Для @PostConstruct вы можете увидетьЖизненный цикл Spring Bean, откуда я взялся?

сложные типы свойств

В большинстве случаев параметры, которые мы передаем приложению, представляют собой простые строки или числа. Однако иногда нам нужно передавать типы данных, такие как List

Перечислите и установите

Предположим, мы предоставляем почтовому модулю список SMTP-сервисов, мы можем добавить это свойство в класс MailModuleProperties

У нас есть два способа автозаполнения свойства списка в Spring Boot.

application.properties

Запишите в виде массива в файле application.properties

application.yml

YAML изначально поддерживает тип списка, поэтому в файле application.yml добавьте:

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

Duration

Spring Boot имеет встроенную поддержку анализа длительности из параметров конфигурации,Официальная документация сайтадает четкие инструкции

Мы можем настроить как числовые миллисекунды, так и текст с единицами измерения:

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

Обычно используются следующие единицы измерения:

  • nsза наносекунды
  • usза микросекунды (микросекунды)
  • msза миллисекунды (миллисекунды)
  • sза секунды (секунды)
  • mза минуты (минуты)
  • hчасами
  • dнесколько дней

DataSize

Как и в случае с Duration, единицей измерения по умолчанию является байт (байт), который можно указать в единице измерения @DataSizeUnit:

добавить конфигурацию

Однако, когда я тестировал, распечатанные результаты отображались в B (байтах).

Общие единицы следующие:

  • B for bytes
  • KB for kilobytes
  • MB for megabytes
  • GB for gigabytes
  • TB for terabytes

пользовательский тип

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

Добавить свойство Weight в MailModuleProperties

Мы можем имитировать DataSize и Duration, чтобы создать свой собственный конвертер (конвертер)

Зарегистрируйте его в контексте Spring Boot.

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

Автозаполнение с обработчиком конфигурации Spring Boot

Добавляем зависимости в проект:

Maven

Gradle

После пересборки проекта процессор конфигурации создаст для нас файл JSON:

Таким образом, будут автоматические напоминания, когда мы пропишем конфигурацию в application.properties и application.yml:

Пометить свойство конфигурации как устаревшее

Процессор конфигурации позволяет нам пометить свойство как устаревшее.

Мы можем добавить@DeprecatedConfigurationPropertyАннотировать метод получения поля, чтобы пометить поле как устаревшее, перестроить проект и посмотреть, что случилось с файлом JSON?

Когда мы переписываем файл конфигурации, мы дали явные устаревшие подсказки:

Суммировать

Весенний ботинок@ConfigurationPropertiesАннотации очень эффективны при связывании типобезопасных Java Bean-компонентов, и мы можем взаимодействовать с их атрибутами аннотаций и@DeprecatedConfigurationPropertyАннотации становятся более удобными для программирования и в то же время делают нашу конфигурацию более модульной.

Дополнительная информация

Считать@ConfigurationPropertiesОтвечают ли аннотации всем нашим потребностям? На самом деле официальный сайт Spring четко дает аннотацию и@ValueСравнение аннотаций:

При использовании выражений SpEL мы можем выбрать только@Valueаннотация

Кроме того, когда я ранее читал исходный код RabbitMQ, я обнаружил, что класс RabbitProperties используется полностью.@ConfigurationPropertiesОсобенности аннотации:

  • deprecated
  • Duration
  • Enum
  • Вложенные свойства

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

о@ConfigurationPropertiesЗдесь рекомендуется использовать аннотацииИсходный код RabbitMQ на Github, просто посмотрите на этот класс, чтобы узнать, как в полной мере использовать эту аннотацию.

Чтобы получить демо-код, ответьте на общедоступную учетную запись «demo» и откройте ссылку для просмотра соответствующей подпапки.

вопрос души

  1. Можете ли вы воспользоваться этими функциями в реальных проектах, чтобы сделать вашу конфигурацию более гибкой и модульной?
  2. При чтении исходников фреймворка как они настраиваются?
  3. Как аннотация @Value дает значение по умолчанию?

инструменты повышения производительности

[center]

Рекомендуемое чтение

--------

Добро пожаловать, чтобы продолжать обращать внимание на публичный номер: «Сун Гун И Бин».

- Обмен галантерейными товарами передовой Java-технологии

- сводка эффективных инструментов

- Анализ и ответы на вопросы собеседования

- Сбор технических данных

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