В этом блоге в основном рассказывается о том, как springboot упрощает для нас большую часть конфигурации, а затем инкапсулирует Starter с исходным кодом.Во-первых, нам нужно поговорить о двух местах, первое — это начальная зависимость springboot, а второе — автоматическая сборка спрингбута;
Зависит от запуска
Нам нужно представить при создании проекта Springbootspring-boot-starter-web
эта зависимость;
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Мы нажимаем на эту зависимость и видим, что эта начальная зависимость объединяет общие веб-зависимости, такие какspring-web
,spring-webmvc
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.1.4.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
<version>2.1.4.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>2.1.4.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.16.Final</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.1.6.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.6.RELEASE</version>
<scope>compile</scope>
</dependency>
Грубо говоря, стартовые зависимости Spring Boot должны снова инкапсулировать часто используемые зависимости, что удобно нам для внедрения и упрощает настройку pom.xml, но что более важно, управление зависимостями передается Spring Boot, и нам не нужно обращать внимание на разные зависимости.Есть ли конфликт между разными версиями, Spring Boot помог нам его рассмотреть, мы можем его использовать!
Прежде чем использовать стартовые зависимости Spring Boot, нам нужноpom.xml
Добавьте конфигурацию в:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
позволятьpom.xml
Наследовать от Spring Bootpom.xml
, в то время как Spring Bootpom.xml
Он определяет зависимости часто используемых фреймворков и соответствующие номера версий, поэтому нам не нужно беспокоиться о конфликтах версий;
автоматическая сборка
Во-первых, мы знаем, что Springboot нужен класс начальной загрузки, который не только является точкой входа приложения, но и играет важную роль в настройке Spring Boot.
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
можно увидеть@SpringBootApplication
Эта аннотация, мы нажимаем на эту аннотацию и обнаруживаем, что она играет роль нескольких аннотаций, что также отражает происхождение и иерархию аннотаций;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
@AliasFor(
annotation = EnableAutoConfiguration.class
)
Class<?>[] exclude() default {};
//........
}
здесь@SpringBootConfiguration
и@ComponentScan
Обратите внимание, первое на самом деле@Configuration
Аннотация заключается в том, чтобы объявить этот класс как класс конфигурации, а последний играет роль включения компонентов автоматического сканирования.
Давайте проанализируем@EnableAutoConfiguration
Эта аннотация, функция этой аннотации - включить функцию автоматической сборки Spring Boot, давайте посмотрим на нее:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
Давайте проанализируем@Import({AutoConfigurationImportSelector.class})
Эту аннотацию мы знаем@Import
Роль заключается в добавлении компонентов в контейнер Spring, и вотAutoConfigurationImportSelector
Этот компонент добавляется в контейнер Spring. то естьAutoConfigurationImportSelector
объявлен как Bean;
Давайте проанализируем@Import
в примечанияхAutoConfigurationImportSelector
Добрый;
protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,
AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
AnnotationAttributes attributes = getAttributes(annotationMetadata);
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
configurations = removeDuplicates(configurations);
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = filter(configurations, autoConfigurationMetadata);
fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationEntry(configurations, exclusions);
}
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
+ "are using a custom packaging, make sure that file is correct.");
return configurations;
}
существуетgetAutoConfigurationEntry
метод сканированияClassPath
все подjar
упаковкаspring.factories
файл, будетspring.factories
документkey
заEnableAutoConfiguration
Все значения , то эти значения на самом деле являются полными именами классов,То есть полное имя класса автоконфигурации, затем классы Spring Boot загружают (отражают) эти полные имена, чтобы добавить эти автоматически настроенные классы в контейнер Spring.
Мы находимspring-boot-autoconfigure-2.1.4.RELEASE.jar
баночка-упаковка, откройте ееspring.factories
файл, обнаружил, что этот файл имеетkey
заEnableAutoConfiguration
пара ключ-значение
вот этоjar
В пакете есть класс автоконфигурации, и вы можете обнаружить, что эти конфигурации автоконфигурации начинаются сxxxAutoConfiguration
Названные в соответствии с правилами именования, эти классы автоматической конфигурации включают в себя классы автоматической конфигурации наших часто используемых фреймворков, таких какaop
,mongo
,redis
иweb
И так далее, это может в основном удовлетворить наши ежедневные потребности в развитии. Например, если нам нужно использовать aop в нашей программе, мы можем напрямую ввести соответствующие зависимости!
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
Возьмем для анализа относительно простой класс конфигурации и посмотрим, как он играет свою роль конфигурации; мы используемHttpEncodingAutoConfiguration
Например, часть кода выглядит следующим образом:
//声明这个类为配置类
@Configuration
//开启ConfigurationProperties功能,同时将配置文件和HttpProperties.class绑定起来
@EnableConfigurationProperties({HttpProperties.class})
//只有在web应用下自动配置类才生效
@ConditionalOnWebApplication(
type = Type.SERVLET
)
//只有存在CharacterEncodingFilter.class情况下 自动配置类才生效
@ConditionalOnClass({CharacterEncodingFilter.class})
//判断配置文件是否存在某个配置spring.http.encoding,如果存在其值为enabled才生效,如果不存在这个配置类也生效。
@ConditionalOnProperty(
prefix = "spring.http.encoding",
value = {"enabled"},
matchIfMissing = true
)
public class HttpEncodingAutoConfiguration {
private final Encoding properties;
public HttpEncodingAutoConfiguration(HttpProperties properties) {
this.properties = properties.getEncoding();
}
//将字符编码过滤器组件添加到 Spring 容器中
@Bean
//仅在该注解规定的类不存在于 spring容器中时,使用该注解的config或者bean声明才会被实例化到容器中
@ConditionalOnMissingBean
public CharacterEncodingFilter characterEncodingFilter() {
CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
filter.setEncoding(this.properties.getCharset().name());
filter.setForceRequestEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.REQUEST));
filter.setForceResponseEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.RESPONSE));
return filter;
}
@Bean
public HttpEncodingAutoConfiguration.LocaleCharsetMappingsCustomizer localeCharsetMappingsCustomizer() {
return new HttpEncodingAutoConfiguration.LocaleCharsetMappingsCustomizer(this.properties);
}
Конфигурация: эта аннотация объявляет, что этот класс является классом конфигурации (так же, как класс конфигурации, который мы обычно пишем, эта аннотация также добавляется к классу).
Енаблеконфигуратионпропертиес: вкл.ConfigurationProperties
функция, то есть файл конфигурации иHttpProperties.class
Этот класс привязывает соответствующие значения файла конфигурации кHttpProperties.class
связанные с переменными, вы можете нажатьHttpProperties.class
зайди и посмотри,
@ConfigurationProperties(
prefix = "spring.http"
)
public static final Charset DEFAULT_CHARSET;
private Charset charset;
private Boolean force;
private Boolean forceRequest;
private Boolean forceResponse;
private Map<Locale, Charset> mapping;
пройти черезConfigurationProperties
Укажите префикс для настройки файлаapplication.properties
с префиксомspring.http
стоимость иHttpProperties.class
Переменные, связанные с классом, можно найти через переменные класса, свойства, которые мы можем установить:charset
,force
,forceRequest
,forceResponse
иmapping
. Кроме тогоConfigurationProperties
Аннотации будутHttpProperties
Класс вводится в контейнер Spring, чтобы стать объектом bean-компонента, потому что, как правило, путь сканирования пакета по умолчанию, такой как springboot,xxxxxxApplication.java
Пакет и все его подпакеты, но бины в некоторых сторонних банках явно не сканируются, и эта аннотация пригодится.Конечно, вы можете сказать, я использую@ComponentScan
Нет, разница между этими двумя аннотациями заключается в следующем:@ComponentScan
Предпосылка состоит в том, что компонент, который вы хотите, уже существует в контейнере компонентов, и@EnableConfigurationProperties
Это позволяет контейнеру автоматически находить нужный класс и регистрировать его как bean-компонент. То есть помимо использования информации о конфигурации, предоставляемой Spring Boot по умолчанию, мы также можем указать информацию о конфигурации через файл конфигурации.
-
ConditionalOnWebApplication:
Цель этой аннотации — автоматическая настройка класса для вступления в силу в веб-приложении. -
ConditionalOnClass:
только существуютCharacterEncodingFilter
Класс автоматической настройки вступит в силу только в том случае, если этот класс используется. -
ConditionalOnProperty:
Определяет, есть ли в конфигурационном файле конфигурация spring.http.encoding.Если она существует, ее значение включено Вступит в силу.Если этого класса конфигурации не существует, он также вступит в силу. -
@ConditionalOnMissingBean:
Только если класс, указанный в аннотации, не существует в контейнере Spring, объявление конфигурации или компонента с использованием этой аннотации будет создано в контейнере.
Можно обнаружить, что следующие аннотацииConditionalXXXX
Эти аннотации являются условными аннотациями, сформулированными Spring, и класс автоконфигурации вступит в силу только при соблюдении условий.
СледующийcharacterEncodingFilter
метод, создайтеCharacterEncodingFilter
Объект, то есть фильтр кодировки символов, одновременно устанавливает связанные свойства, а затем возвращает объект, через@Bean
Аннотация для добавления возвращаемого объекта в контейнер Spring. Таким образом настраивается компонент фильтра кодировки символов, и обычно нам нужно настроить в web.xml следующее:
<filter>
<filter-name>springUtf8Encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>springUtf8Encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
На этом мы закончили разбор принципа, давайте инкапсулируем аналогичный самостоятельно.spring-boot-starter-aop
Инкапсулировать стартер
1, Спецификация разработки SpringBoot Starter
- 1. Использование имени
spring-boot-starter-xxx
,вxxx
это наше конкретное имя пакета, если оно интегрированоSpring Cloud
затем используйтеspring-cloud-starter-xxx
- 2, обычно нужно подготовить два
jar
Файлы, один из которых не содержит никакого кода, отвечает только за импорт связанных jar-файлов, а другой содержит основной код
подобноnacos
Стартер, интегрированный с Spring Cloud, выглядит следующим образом:
БолееStarter
спецификация продукции, мы можем просмотретьОфициальная документация сайта
2, этапы разработки Starter
Мы создаем именнуюokay-spring-boot-starter
и ввести связанные зависимости:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<dependencyManagement>
<!-- 我们是基于Springboot的应用 -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.4.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Поскольку нам нужно использовать соответствующие аннотации, предоставляемые Springboot, и использовать функцию автоматической настройки, предоставляемую Springboot, мы должны ввестиspring-boot-autoconfigure
иspring-boot-dependencies
две зависимости.
3, создайте класс автоматической конфигурации
Вообще говоря, мы можем захотеть предварительно внедрить некоторые из наших собственных bean-компонентов при запуске Springboot.На данный момент нам нужно создать свой собственный класс автоматической конфигурации, обычно используяxxxxAutoConfiguration
. Здесь аналогично вышеописанномуHttpEncodingAutoConfiguration
, мы подражаемHttpEncodingAutoConfiguration
создать новыйOkayStarterAutoConfiguration
класс конфигурации;
@Configuration
@EnableConfigurationProperties(OkayProperties.class)
@ConditionalOnClass(Okay.class)
@ConditionalOnWebApplication
public class OkayStarterAutoConfiguration {
@Bean
@ConditionalOnMissingBean
/**
* 当存在okay.config.enable=true的配置时,这个Okay bean才生效
*/
@ConditionalOnProperty(prefix = "okay.config", name = "enable", havingValue = "true")
public Okay defaultStudent(OkayProperties okayProperties) {
Okay okay = new Okay();
okay.setPlatform(okayProperties.getPlatform());
okay.setChannel(okayProperties.getChannel());
okay.setEnable(okayProperties.getEnable());
return okay;
}
}
Значение каждой аннотации здесь было объяснено выше, поэтому я не буду объяснять здесь слишком много;
создать новыйOkayProperties
, объявляет, какие элементы конфигурации может настроить пользователь пускового устройства.
@ConfigurationProperties(prefix = "okay.config")
public class OkayProperties {
private String platform;
private String channel;
private Boolean enable;
public String getPlatform() {
return platform;
}
public void setPlatform(String platform) {
this.platform = platform;
}
public String getChannel() {
return channel;
}
public void setChannel(String channel) {
this.channel = channel;
}
public Boolean getEnable() {
return enable;
}
public void setEnable(Boolean enable) {
this.enable = enable;
}
@Override
public String toString() {
return "OkayProperties{" +
"platform='" + platform + '\'' +
", channel='" + channel + '\'' +
", enable=" + enable +
'}';
}
}
существуетresources
Создайте новый в каталогеMETA-INF
каталог и создатьspring.factories
документ
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.haoxiaoyong.okay.starter.config.OkayStarterAutoConfiguration
Это в основном то же самое, что и исходный код, который мы объяснили выше!
Используйте наш собственный стартер
Создайте новый проект Springboot и введите наши собственные зависимости maven:
<dependency>
<groupId>cn.haoxiaoyong.okay</groupId>
<artifactId>okay-spring-boot-starter</artifactId>
<version>0.0.2-SNAPSHO</version>
</dependency>
И настроить в конфигурационном файле application.yml
Вы видите, как умно это будет автоматически предложено!
okay:
config:
platform: pdd
channel: ws
enable: true
@RestController
@Slf4j
public class OkController {
@Autowired
Okay okay;
@RequestMapping("okay")
public String testOkay() {
log.info(okay.getChannel() + " " + okay.getPlatform() + " " + okay.getEnable());
return okay.getChannel() + " " + okay.getPlatform() + " " + okay.getEnable();
}
}
Ввод браузера: localhost:8082/хорошо, консоль выводит:
Этот пример просто показывает логический эффект, этоИспользуйте пользовательский Starter и сделайте простую кровать карты
Пример адреса:GitHub.com/смешно с…