Как устроены различные Starters, созданные в SpringBoot? Исходный код SpringBoot (шесть)

Spring Boot
Как устроены различные Starters, созданные в SpringBoot? Исходный код SpringBoot (шесть)

Примечание. Анализ исходного кода соответствует SpringBoot версии 2.1.0.RELEASE.

1 Уроки прошлого

Эта статья продолжаетКак значения свойств внешней конфигурации привязаны к свойствам класса XxxProperties? --Исходный код SpringBoot (5)

Ознакомившись с прошлым и узнав новое, давайте кратко повторим содержание предыдущей статьи, в которой мы разобрали SpringBootКак значения свойств внешней конфигурации привязаны к свойствам класса XxxPropertiesСоответствующий исходный код, важные этапы привязки внешних свойств резюмируются следующим образом:

  1. прежде всего@EnableConfigurationPropertiesаннотацияimportохватыватьEnableConfigurationPropertiesImportSelectorпостпроцессор;
  2. EnableConfigurationPropertiesImportSelectorпостпроцессор вSpringзарегистрирован в контейнереConfigurationPropertiesBeanRegistrarиConfigurationPropertiesBindingPostProcessorRegistrarэти двоеbean;
  3. вConfigurationPropertiesBeanRegistrarВ направленииSpringзарегистрирован в контейнереXxxPropertiesТипbean;ConfigurationPropertiesBindingPostProcessorRegistrarВ направленииSpringзарегистрирован в контейнереConfigurationBeanFactoryMetadataиConfigurationPropertiesBindingPostProcessorДва задних процессора;
  4. ConfigurationBeanFactoryMetadataПостпроцессор инициализируетсяbean factoryкогда@BeanМетаданные аннотации сохраняются для использования в связанной логике последующей привязки атрибутов внешней конфигурации;
  5. ConfigurationPropertiesBindingPostProcessorПостпроцессоры привязывают значения свойств внешней конфигурации кXxxPropertiesЛогика свойства класса делегируетсяConfigurationPropertiesBinderобъект, тоConfigurationPropertiesBinderОбъекты и в конечном итоге делегировать привязку логической логикиBinderобъект для завершения.

Видно, что главное вышеШаг 5.

2 Введение

Все мы знаем, что SpringBoot имеет встроенные различныеStarterЗапуск зависимостей нам очень удобно использовать, что значительно сокращает нашу работу по разработке. имеютStarterЗапуская зависимости, нам не нужно думать о том, какая библиотека нужна этому проекту, библиотекаgroupIdиartifactIdчто это? Не беспокойтесь о том, не будет ли он конфликтовать с другими зависимостями после импорта этой версии библиотеки.

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

Поэтому мы пока не будем анализировать исходный код автоматической настройки SpringBoot.Поскольку взаимосвязь между зависимостями при запуске и автоматической настройкой тесно связана, в этой статье мы сначала рассмотрим построение проекта maven для анализа макроскопического анализа, который мы обычно используют.Различные встроенные SpringBootStarterКак он устроен?

3 необязательных тега Maven для транзитивных зависимостей

При анализе различных встроенных в SpringBootStarterПрежде чем строить принцип, давайте сначала разберемся с Maven.optionalярлык, потому что этот ярлык играет жизненно важную роль. знатокoptionalМетка представляет значение необязательной зависимости, то есть нетранзитивной.Ниже приведен каштан для иллюстрации.

Такие какA,BиCтри библиотеки,CполагатьсяB,BполагатьсяA. Давайте взглянем на три библиотеки нижеpom.xmlдокумент:

// A的pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

	<groupId>com.ymbj</groupId>
        <artifactId>A</artifactId>
	<version>1.0-SNAPSHOT</version>

</project>


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

	<groupId>com.ymbj</groupId>
        <artifactId>B</artifactId>
	<version>1.0-SNAPSHOT</version>

    <!--注意是可选依赖-->
    <dependencies>
        <dependency>
            <groupId>com.ymbj</groupId>
            <artifactId>A</artifactId>
            <version>1.0-SNAPSHOT</version>
	    <optional>true</optional>
        </dependency>
    </dependencies>

</project>

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

	<groupId>com.ymbj</groupId>
        <artifactId>C</artifactId>
	<version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>com.ymbj</groupId>
            <artifactId>B</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

тройка лидеровA,BиCбиблиотекаpom.xmlзнать,Bбиблиотечные зависимостиAбиблиотека, затемCБиблиотека снова зависитBбиблиотека, то подумай об этом,Пакетная сборка MavenCПосле библиотеки,AБиблиотека была импортирована?

Ответ определеннонет,так какBимпорт библиотекиAиспользуются библиотечные зависимости<optional>true</optional>, подходя к МавенуoptionalЗначение метки установлено наtrue,В настоящее времяCповторное введение библиотекиBбиблиотечные зависимости,AБиблиотеки не импортируются вCбиблиотека.

В то же время есть еще один, связанный с транзитивными зависимостями Maven.exclusionsМетка, что означает исключение подзависимости библиотеки, которая здесь подробно описываться не будет.

4 Как устроены различные Starters, созданные в SpringBoot?

Теперь давайте изучим различные встроенные средства SpringBoot.StarterВ конце концов, как его построить?

все еще помнюКак анализировать модули и структуру исходного кода SpringBoot?В этой статье анализируются отношения между модулями в SpringBoot? Давайте рассмотрим внутреннюю диаграмму модулей исходного кода SpringBoot:

Рисунок 1

Мы все знаем, что SpringBootStarterСуть принципа построения заключается в автоматической настройке, поэтому из рисунка 1 вы можете увидеть внутреннее продолжение исходного кода проекта SpringBoot.StarterЕсть четыре модуля, связанные с его автоматической настройкой:spring-boot-starters,spring-boot-actuator-autoconfigure,spring-boot-autoconfigureиspring-boot-test-autoconfigure. Пожалуйста, ознакомьтесь с ролью каждого модуляКак анализировать модули и структуру исходного кода SpringBoot?Эта статья не будет повторяться здесь.

Так,spring-boot-startersМодули связаны со следующими тремя модулями автоконфигурации.xxx-autoconfigureКакая связь между модулями?

Теперь давайте посмотримspring-boot-startersКакова структура модуля?

фигура 2

Из рисунка 2 видно, чтоspring-boot-startersМодуль содержит различные встроенные SpringBootstarter:spring-boot-starter-xxx. Из-за различных встроенных в SpringBootstarterслишком много, с нашим обычнымspring-boot-starter-webНачните полагаться на исследования.

давайте сначала посмотримspring-boot-starter-webВнутренняя структура модуля:

изображение 3

можно увидетьspring-boot-starter-webТолько внутри модуля.flattened-pom.xmlиpom.xmlдокумент,без кода! Немного неожиданно. Мы все знаем, что когда мы хотим использовать веб-функции SpringBoot, нам нужно ввестиspring-boot-starter-webВы можете начать полагаться на него, и теперьspring-boot-starter-webВ модуле нет строки кода, тогдаspring-boot-starter-webКак именно он устроен? Будет ли он таким же, как показано на рисунке 1?spring-boot-autoconfigureМодуль автоконфигурации связан?

В этот момент нам нужно посмотреть наspring-boot-starter-webмодульныйpom.xmlсодержание документа:

Рисунок 4

Как видно из рисунка 4,spring-boot-starter-webмодуль зависит отspring-boot-starter,spring-boot-starter-tomcat,spring-webиspring-webmvcОжидание модуля, зависимости нетspring-boot-autoconfigureАвтоматически настраивайте модули!

так какspring-boot-starter-webМодуль должен следоватьspring-boot-autoconfigureсвязанных с модулями автоконфигурации, поэтомуspring-boot-starter-webМодуль должен быть косвенно зависимspring-boot-autoconfigureАвтоматически настраивать модули.

Рисунок 4 Отмечен меткой «В фокусе»spring-boot-starterМодули составляют подавляющее большинствоspring-boot-starter-xxxБазовый модуль, от которого зависит модуль, является ядромStarter, включая автоматическую настройку, ведение журнала иYAMLслужба поддержки. давайте обратим вниманиеspring-boot-starterизpom.xmlфайл, возможно, это зависит отspring-boot-autoconfigureАвтоматически настраивать модули.

Рисунок 5

Как видно из рисунка 5, наша предыдущая гипотеза не является ошибочной.точноspring-boot-starterмодуль зависит отspring-boot-autoconfigureАвтоматически настраивайте модули!Итак, здесь мы можем сделать вывод:spring-boot-starter-webВ модуле нет ни строчки кода, но он проходитspring-boot-starterмодулькосвенныйзависел отspring-boot-autoconfigureМодуль автоматически настраивается для реализации функций, от которых он зависит при запуске.

Теперь давайте посмотрим наspring-boot-autoconfigureВнутренняя структура пакета модуля автоконфигурации:

Изображение 6

Из красного прямоугольника на рис. 6 мы можем узнать, чтоspring-boot-starter-webФункция автоконфигурации зависимостей запуска изначально была созданаspring-boot-autoconfigureмодульныйwebРеализован классами под пакетом.

иди тудаspring-boot-starter-webМы разобрались с основными принципами построения стартовых зависимостей, но есть особенно важный ключевой момент, до которого мы еще не добрались. Этот ключевой момент похож на MavenoptionalЭтикетки играют свою роль.

Чтобы добраться до этого момента, давайте сначала подумаем о проблеме: обычно мы разрабатываемwebПочему был представлен проект?spring-boot-starter-webПосле этой начальной зависимостиspring-boot-autoconfigureмодульныйwebБудут ли соответствующие классы автоконфигурации работать автоматически?

Мы должны знать, что класс автоматической настройки часто работает из-заclasspathЕсть класс вDispatcherServletAutoConfigurationЭтот класс автоматически настраивается как точка входа, чтобы лучше понять суть. Первый взглядDispatcherServletAutoConfigurationКаковы условия автоматической настройки?

Рисунок 7

Как показано на рисунке 7,DispatcherServletAutoConfigurationОдним из условий возможности автоматической настройки является@ConditionalOnClass(DispatcherServlet.class), то есть толькоclasspathсуществуют вDispatcherServlet.classЭтот класс,DispatcherServletAutoConfigurationАвтоматическая логика, связанная с конфигурацией, для работы.

иDispatcherServletЭтот класс находится вspring-webmvcВ этой библиотеке зависимостей, как показано на следующем рисунке:

Рисунок 8

Теперь давайте посмотрим наspring-boot-autoconfigureмодульныйpom.xmlВведение в файлspring-webmvcСлучай этой зависимости:

Рисунок 9

Как показано на рисунке 9,spring-boot-autoconfigureмодуль импортированspring-webmvcКогда эта зависимостьoptionalустановить какtrue, оказывается необязательной зависимостью. которыйspring-webmvcЭта зависимая библиотека будет импортирована только вspring-boot-autoconfigureмодули без импорта в косвенные зависимостиspring-boot-autoconfigureмодульныйspring-boot-starter-webЭто начало зависит от.

В этот момент давайте посмотрим наspring-boot-starter-webизpom.xmlЗависимости файлов:

Рисунок 10

Как показано на рисунке 10,spring-boot-starter-webЗависит от запускаявныйпредставилspring-webmvcЭта библиотека зависимостей, то есть введениеspring-webmvcнетoptionalЭтот ярлык, и потомуDispatcherServletЭтот класс находится вspring-webmvcв этой библиотеке зависимостей, таким образомclasspathсуществуют вDispatcherServletэтот класс, поэтомуDispatcherServletAutoConfigurationЭтот класс автоматической настройки вступает в силу. Конечно,webЭто также принцип других классов автоматической конфигурации.

На данный момент мы также понимаемspring-boot-autoconfigureПочему модуль должен быть импортирован?spring-webmvcЭта зависимость является необязательной, и ее цель состоит в том, чтобыspring-boot-starter-webМожет быть явно введен в начальных зависимостяхspring-webmvcЭта зависимость (это играет решающую роль), поэтому нам нужно только представить веб-проектspring-boot-starter-webЗависимости запуска, тогда вступят в силу классы автоматической настройки, связанные с веб-сайтом, так что вы сможете использовать их сразу после установки.spring-boot-starter-webПринцип построения этой пусковой зависимости.

упоминалось ранееspring-boot-starter-actuator,spring-boot-starter-testи другие встроенныеspring-boot-starter-xxxТо же верно и для принципа построения исходных зависимостей, за исключением того, чтоspring-boot-starter-actuatorзависит отspring-boot-actuator-autoconfigure,spring-boot-starter-testзависит отspring-boot-test-autoconfigureЭто всего лишь модуль, поэтому я не буду вдаваться в подробности.

считать:spring-boot-actuator-autoconfigureизpom.xmlФайл представляет более 20 необязательных зависимостей, и почемуspring-boot-starter-actuatorЗависимости запуска только вводятсяmicrometer-coreА как быть с этой зависимостью?

5 Настройте Starter, имитируя структуру пакета SpringBoot

Предыдущий анализ различных встроенных SpringBootStarterПринцип построения, теория и практика, то если можно попрактиковаться на заказStarterДаже лучше.

Ниже приведен обычайStarterпростоDemo,этоDemoполная имитацияSpringBootвстроенныйStarterВнутреннюю структуру пакета написать, чтобы узнать больше о различных встроенных SpringBootStarterПолезен принцип построения.

Ниже этоDemoАдрес github рекомендуется заинтересованным друзьям.Настройте Starter, имитируя внутреннюю структуру Springboot.. Кроме того, как настроить одинStarter, вы можете обратиться к Mybatisspring-boot-starterКак писать.

6 Резюме

Ну и всякие встроенные в SpringBootStarterЭто конец разбора принципа построения , теперь резюмируем ключевые моменты:

  1. spring-boot-starter-xxxНачальные зависимости не имеют ни строчки кода, а прямо или косвенно зависятxxx-autoconfigureмодуль, покаxxx-autoconfigureмодуль берет на себяspring-boot-starter-xxxНачните полагаться на реализацию автоматической настройки;
  2. xxx-autoconfigureМодули автоматической конфигурации вводят некоторые необязательные зависимости, эти необязательные зависимости не будут переданыspring-boot-starter-xxxВ начальных зависимостях это сборка начальных зависимостей.ключевой момент;
  3. spring-boot-starter-xxxЗависит от запускаявныйВведены некоторые необязательные зависимости для работы автоконфигурации;
  4. После первых трех шагов подготовки, пока наш проект вводит начальную зависимость, ее можно использовать «из коробки», вместо того, чтобы вручную создавать некоторыеbeanЖдать.

В связи с ограниченным уровнем автора, если есть ошибки в тексте, просьба указать, спасибо.

Ссылаться на: 1,Глубокое понимание транзитивности зависимостей Maven