2-springboot自定配置流程

19 篇文章 1 订阅
5 篇文章 0 订阅

1.父项

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.5.4</version>
</parent>
<!--查看其父项的父项配置:-->
<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-dependencies</artifactId>
  <version>2.5.4</version>
</parent>
<!--猜测可能配置很多的依赖配置项:-->
<properties>
  <activemq.version>5.16.3</activemq.version>
  <antlr2.version>2.7.7</antlr2.version>
  <appengine-sdk.version>1.9.91</appengine-sdk.version>
  <artemis.version>2.17.0</artemis.version>
  <aspectj.version>1.9.7</aspectj.version>
  <assertj.version>3.19.0</assertj.version>
  <atomikos.version>4.0.6</atomikos.version>
  <awaitility.version>4.0.3</awaitility.version>
  <build-helper-maven-plugin.version>3.2.0</build-helper-maven-plugin.version>
  <byte-buddy.version>1.10.22</byte-buddy.version>
  <caffeine.version>2.9.2</caffeine.version>
  <cassandra-driver.version>4.11.3</cassandra-driver.version>
  <classmate.version>1.5.1</classmate.version>
  <commons-codec.version>1.15</commons-codec.version>
  <commons-dbcp2.version>2.8.0</commons-dbcp2.version>
  <commons-lang3.version>3.12.0</commons-lang3.version>
  <commons-pool.version>1.6</commons-pool.version>
  <commons-pool2.version>2.9.0</commons-pool2.version>
  <couchbase-client.version>3.1.7</couchbase-client.version>
  <db2-jdbc.version>11.5.6.0</db2-jdbc.version>
  <dependency-management-plugin.version>1.0.11.RELEASE</dependency-management-plugin.version>
  <derby.version>10.14.2.0</derby.version>
  <dropwizard-metrics.version>4.1.25</dropwizard-metrics.version>
  <ehcache.version>2.10.9.2</ehcache.version>
  <ehcache3.version>3.9.5</ehcache3.version>
  <elasticsearch.version>7.12.1</elasticsearch.version>
  <embedded-mongo.version>3.0.0</embedded-mongo.version>
  <flyway.version>7.7.3</flyway.version>
  <freemarker.version>2.3.31</freemarker.version>
  <git-commit-id-plugin.version>4.0.5</git-commit-id-plugin.version>
  <glassfish-el.version>3.0.3</glassfish-el.version>
  <glassfish-jaxb.version>2.3.5</glassfish-jaxb.version>
  <groovy.version>3.0.8</groovy.version>
  <gson.version>2.8.7</gson.version>
  <h2.version>1.4.200</h2.version>
  <hamcrest.version>2.2</hamcrest.version>
  <hazelcast.version>4.1.5</hazelcast.version>
  <hazelcast-hibernate5.version>2.2.1</hazelcast-hibernate5.version>
  <hibernate.version>5.4.32.Final</hibernate.version>
  <hibernate-validator.version>6.2.0.Final</hibernate-validator.version>
  <hikaricp.version>4.0.3</hikaricp.version>
  <hsqldb.version>2.5.2</hsqldb.version>
  <htmlunit.version>2.49.1</htmlunit.version>
  <httpasyncclient.version>4.1.4</httpasyncclient.version>
  <httpclient.version>4.5.13</httpclient.version>
  <httpclient5.version>5.0.4</httpclient5.version>
  <httpcore.version>4.4.14</httpcore.version>
  <httpcore5.version>5.1.1</httpcore5.version>
  <infinispan.version>12.1.7.Final</infinispan.version>
  <influxdb-java.version>2.21</influxdb-java.version>
  <jackson-bom.version>2.12.4</jackson-bom.version>
  <jakarta-activation.version>1.2.2</jakarta-activation.version>
  <jakarta-annotation.version>1.3.5</jakarta-annotation.version>
  <jakarta-jms.version>2.0.3</jakarta-jms.version>
  <jakarta-json.version>1.1.6</jakarta-json.version>
  <jakarta-json-bind.version>1.0.2</jakarta-json-bind.version>
  <jakarta-mail.version>1.6.7</jakarta-mail.version>
  <jakarta-persistence.version>2.2.3</jakarta-persistence.version>
  <jakarta-servlet.version>4.0.4</jakarta-servlet.version>
  <jakarta-servlet-jsp-jstl.version>1.2.7</jakarta-servlet-jsp-jstl.version>
  <jakarta-transaction.version>1.3.3</jakarta-transaction.version>
  <jakarta-validation.version>2.0.2</jakarta-validation.version>
  <jakarta-websocket.version>1.1.2</jakarta-websocket.version>
  <jakarta-ws-rs.version>2.1.6</jakarta-ws-rs.version>
  <jakarta-xml-bind.version>2.3.3</jakarta-xml-bind.version>
  <jakarta-xml-soap.version>1.4.2</jakarta-xml-soap.version>
  <jakarta-xml-ws.version>2.3.3</jakarta-xml-ws.version>
  <janino.version>3.1.6</janino.version>
  <javax-activation.version>1.2.0</javax-activation.version>
  <javax-annotation.version>1.3.2</javax-annotation.version>
  <javax-cache.version>1.1.1</javax-cache.version>
  <javax-jaxb.version>2.3.1</javax-jaxb.version>
  <javax-jaxws.version>2.3.1</javax-jaxws.version>
  <javax-jms.version>2.0.1</javax-jms.version>
  <javax-json.version>1.1.4</javax-json.version>
  <javax-jsonb.version>1.0</javax-jsonb.version>
  <javax-mail.version>1.6.2</javax-mail.version>
  <javax-money.version>1.1</javax-money.version>
  <javax-persistence.version>2.2</javax-persistence.version>
  <javax-transaction.version>1.3</javax-transaction.version>
  <javax-validation.version>2.0.1.Final</javax-validation.version>
  <javax-websocket.version>1.1</javax-websocket.version>
  <jaxen.version>1.2.0</jaxen.version>
  <jaybird.version>4.0.3.java8</jaybird.version>
  <jboss-logging.version>3.4.2.Final</jboss-logging.version>
  <jboss-transaction-spi.version>7.6.1.Final</jboss-transaction-spi.version>
  <jdom2.version>2.0.6</jdom2.version>
  <jedis.version>3.6.3</jedis.version>
  <jersey.version>2.33</jersey.version>
  <jetty-el.version>9.0.48</jetty-el.version>
  <jetty-jsp.version>2.2.0.v201112011158</jetty-jsp.version>
  <jetty-reactive-httpclient.version>1.1.10</jetty-reactive-httpclient.version>
  <jetty.version>9.4.43.v20210629</jetty.version>
  <jmustache.version>1.15</jmustache.version>
  <johnzon.version>1.2.14</johnzon.version>
  <jolokia.version>1.6.2</jolokia.version>
  <jooq.version>3.14.13</jooq.version>
  <json-path.version>2.5.0</json-path.version>
  <json-smart.version>2.4.7</json-smart.version>
  <jsonassert.version>1.5.0</jsonassert.version>
  <jstl.version>1.2</jstl.version>
  <jtds.version>1.3.1</jtds.version>
  <junit.version>4.13.2</junit.version>
  <junit-jupiter.version>5.7.2</junit-jupiter.version>
  <kafka.version>2.7.1</kafka.version>
  <kotlin.version>1.5.21</kotlin.version>
  <kotlin-coroutines.version>1.5.1</kotlin-coroutines.version>
  <lettuce.version>6.1.4.RELEASE</lettuce.version>
  <liquibase.version>4.3.5</liquibase.version>
  <log4j2.version>2.14.1</log4j2.version>
  <logback.version>1.2.5</logback.version>
  <lombok.version>1.18.20</lombok.version>
  <mariadb.version>2.7.4</mariadb.version>
  <maven-antrun-plugin.version>1.8</maven-antrun-plugin.version>
  <maven-assembly-plugin.version>3.3.0</maven-assembly-plugin.version>
  <maven-clean-plugin.version>3.1.0</maven-clean-plugin.version>
  <maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
  <maven-dependency-plugin.version>3.1.2</maven-dependency-plugin.version>
  <maven-deploy-plugin.version>2.8.2</maven-deploy-plugin.version>
  <maven-enforcer-plugin.version>3.0.0</maven-enforcer-plugin.version>
  <maven-failsafe-plugin.version>2.22.2</maven-failsafe-plugin.version>
  <maven-help-plugin.version>3.2.0</maven-help-plugin.version>
  <maven-install-plugin.version>2.5.2</maven-install-plugin.version>
  <maven-invoker-plugin.version>3.2.2</maven-invoker-plugin.version>
  <maven-jar-plugin.version>3.2.0</maven-jar-plugin.version>
  <maven-javadoc-plugin.version>3.2.0</maven-javadoc-plugin.version>
  <maven-resources-plugin.version>3.2.0</maven-resources-plugin.version>
  <maven-shade-plugin.version>3.2.4</maven-shade-plugin.version>
  <maven-source-plugin.version>3.2.1</maven-source-plugin.version>
  <maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
  <maven-war-plugin.version>3.3.1</maven-war-plugin.version>
  <micrometer.version>1.7.3</micrometer.version>
  <mimepull.version>1.9.15</mimepull.version>
  <mockito.version>3.9.0</mockito.version>
  <mongodb.version>4.2.3</mongodb.version>
  <mssql-jdbc.version>9.2.1.jre8</mssql-jdbc.version>
  <mysql.version>8.0.26</mysql.version>
  <nekohtml.version>1.9.22</nekohtml.version>
  <neo4j-java-driver.version>4.2.7</neo4j-java-driver.version>
  <netty.version>4.1.67.Final</netty.version>
  <netty-tcnative.version>2.0.40.Final</netty-tcnative.version>
  <oauth2-oidc-sdk.version>9.9.1</oauth2-oidc-sdk.version>
  <nimbus-jose-jwt.version>9.10.1</nimbus-jose-jwt.version>
  <ojdbc.version>19.3.0.0</ojdbc.version>
  <okhttp3.version>3.14.9</okhttp3.version>
  <oracle-database.version>21.1.0.0</oracle-database.version>
  <pooled-jms.version>1.2.2</pooled-jms.version>
  <postgresql.version>42.2.23</postgresql.version>
  <prometheus-pushgateway.version>0.10.0</prometheus-pushgateway.version>
  <quartz.version>2.3.2</quartz.version>
  <querydsl.version>4.4.0</querydsl.version>
  <r2dbc-bom.version>Arabba-SR10</r2dbc-bom.version>
  <rabbit-amqp-client.version>5.12.0</rabbit-amqp-client.version>
  <reactive-streams.version>1.0.3</reactive-streams.version>
  <reactor-bom.version>2020.0.10</reactor-bom.version>
  <rest-assured.version>4.3.3</rest-assured.version>
  <rsocket.version>1.1.1</rsocket.version>
  <rxjava.version>1.3.8</rxjava.version>
  <rxjava-adapter.version>1.2.1</rxjava-adapter.version>
  <rxjava2.version>2.2.21</rxjava2.version>
  <saaj-impl.version>1.5.3</saaj-impl.version>
  <selenium.version>3.141.59</selenium.version>
  <selenium-htmlunit.version>2.49.1</selenium-htmlunit.version>
  <sendgrid.version>4.7.4</sendgrid.version>
  <servlet-api.version>4.0.1</servlet-api.version>
  <slf4j.version>1.7.32</slf4j.version>
  <snakeyaml.version>1.28</snakeyaml.version>
  <solr.version>8.8.2</solr.version>
  <spring-amqp.version>2.3.10</spring-amqp.version>
  <spring-batch.version>4.3.3</spring-batch.version>
  <spring-data-bom.version>2021.0.4</spring-data-bom.version>
  <spring-framework.version>5.3.9</spring-framework.version>
  <spring-hateoas.version>1.3.3</spring-hateoas.version>
  <spring-integration.version>5.5.3</spring-integration.version>
  <spring-kafka.version>2.7.6</spring-kafka.version>
  <spring-ldap.version>2.3.4.RELEASE</spring-ldap.version>
  <spring-restdocs.version>2.0.5.RELEASE</spring-restdocs.version>
  <spring-retry.version>1.3.1</spring-retry.version>
  <spring-security.version>5.5.2</spring-security.version>
  <spring-session-bom.version>2021.0.2</spring-session-bom.version>
  <spring-ws.version>3.1.1</spring-ws.version>
  <sqlite-jdbc.version>3.34.0</sqlite-jdbc.version>
  <sun-mail.version>1.6.7</sun-mail.version>
  <thymeleaf.version>3.0.12.RELEASE</thymeleaf.version>
  <thymeleaf-extras-data-attribute.version>2.0.1</thymeleaf-extras-data-attribute.version>
  <thymeleaf-extras-java8time.version>3.0.4.RELEASE</thymeleaf-extras-java8time.version>
  <thymeleaf-extras-springsecurity.version>3.0.4.RELEASE</thymeleaf-extras-springsecurity.version>
  <thymeleaf-layout-dialect.version>2.5.3</thymeleaf-layout-dialect.version>
  <tomcat.version>9.0.52</tomcat.version>
  <unboundid-ldapsdk.version>4.0.14</unboundid-ldapsdk.version>
  <undertow.version>2.2.10.Final</undertow.version>
  <versions-maven-plugin.version>2.8.1</versions-maven-plugin.version>
  <webjars-hal-browser.version>3325375</webjars-hal-browser.version>
  <webjars-locator-core.version>0.46</webjars-locator-core.version>
  <wsdl4j.version>1.6.3</wsdl4j.version>
  <xml-maven-plugin.version>1.0.2</xml-maven-plugin.version>
  <xmlunit2.version>2.8.2</xmlunit2.version>
</properties>

果真他来真正管理Spring Boot应用里面的所有依赖版本
Spring Boot的版本仲裁中心;
以后我们导入依赖默认是不需要写版本;(没有在dependencies里面管理的依赖自然需要声明版本号)

2.启动器

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

spring-boot-starter:spring-boot场景启动器;帮我们导入了web模块正常运行所依赖的组件;
Spring Boot将所有的功能场景都抽取出来,做成一个个的starters(启动器),只需要在项目里面引入这些starter相关场景的所有依赖都会导入进来。要用什么功能就导入什么场景的启动器
查看官方:所有的启动器
注意:并不是所有的启动器都包含了,比如mybatis的启动器,这里并没有包含,如果需要使用,则需要自己受到导入。
spring-boot-starter-parent 主要作用就是版本的统一管理。那么所依赖的jar是如何得来的呢?又是怎么管理的呢?
查看spring-boot-starter-web依赖的源码:

<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <version>2.5.4</version>
    <scope>compile</scope>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-json</artifactId>
    <version>2.5.4</version>
    <scope>compile</scope>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <version>2.5.4</version>
    <scope>compile</scope>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.3.9</version>
    <scope>compile</scope>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.3.9</version>
    <scope>compile</scope>
  </dependency>
</dependencies>

可以发现spring-boot-starter-web依赖启动器的作用主要是提供了web开发场景所需要的所有底层依赖。对web开发所需依赖进行了统一管理。通过该依赖我们可以猜想器他的启动也是这么管理的,开发中只需要导入对应的启动器(starter)就可以使用对应的场景开发了。

3.SpringBoot自动配置

主程序:

@SpringBootApplication
public class HelloWorldApplication {
    public static void main(String[] args) {
        /*启动应用程序*/
        SpringApplication.run(HelloWorldApplication.class,args);
    }
}

@SpringBootApplication: Spring Boot应用标注在某个类上说明这个类是SpringBoot的主配置类,SpringBoot就应该运行这个类的main方法来启动SpringBoot应用。
@SpringBootApplication标注类中的main()方法是程序启动入口,它能够扫描spring组件并自动配置spring boot,那么它是如何实现自动配置呢?
查看源码:

@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 {
....
}

可以发现**@SprinbBootApplication**是一个组合注解。由
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan

3个核心注解组成。
①查看@SpringBootConfiguration的源码:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
@Indexed
public @interface SpringBootConfiguration {
}

@Configuration的源码:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
}

通过以上源码我们可知道其实**@SpringBootConfiguration的底层是@Configuration**,而**@Configuration底层为@Component** 那么被**@SprinbBootApplication标注的类其实spring的一个配置类。也就是spring容器中一个组件而已。只是springboot将其封装了而已。
②查看
@EnableAutoConfiguration**的源码:
该注解表示开启自动配置功能。

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
}

发现其主要有由:

@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})

两个注解的组合。

@AutoConfigurationPackage的源码:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({Registrar.class})
public @interface AutoConfigurationPackage {
}

发现其底层是一个**@Import({Registrar.class})** 主要作用是向容器中注册组件用的:
Registrar源码:

static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
    Registrar() {
    }


    public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
        AutoConfigurationPackages.register(registry, (String[])(new AutoConfigurationPackages.PackageImports(metadata)).getPackageNames().toArray(new String[0]));
    }


    public Set<Object> determineImports(AnnotationMetadata metadata) {
        return Collections.singleton(new AutoConfigurationPackages.PackageImports(metadata));
    }
}

通过Debug模式启动项目,会发现标红部分获取的是主程序启动类所在的目录com.qwy.也就是**@AutoConfigurationPackage**注解的主要作用就获取主程序所在的目录。为后续组件扫描器指定要扫描的位置。因此在定义项目包结构时,要符合规范:项目主程序启动类要定义在最外层的根目录位置,其他的在根目录位置内部建立的子包和类才能够被扫描器扫描到。
**@Import({AutoConfigurationImportSelector.class})**的AutoConfigurationImportSelector类的源码:

protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
    if (!this.isEnabled(annotationMetadata)) {
        return EMPTY_ENTRY;
    } else {
        AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
        List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
        configurations = this.removeDuplicates(configurations);
        Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
        this.checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        configurations = this.getConfigurationClassFilter().filter(configurations);
        this.fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
    }
}

getAutoConfigurationEntry() 该方法主要是筛选出当前项目中需要启动的自定配置类XxxAutoConfiguration,从而实现当前项目所需要的自动配置环境。
该方法中主要的代码:

this.getCandidateConfigurations(annotationMetadata, attributes); 该方法获取spring boot提供的自动配置依赖(META-INF/spring.factories)筛选出所有的自动配置类XxxAutoConfiguration(该版本中有131)
this.getConfigurationClassFilter().filter(configurations); 该方法作用就是对以上所有的XxxAutoConfiguration进一步进行筛选,根据pom.xml文件中添加的依赖最终筛选出符合当前项目运行所需要的自动配置类。
META-INF/spring.factories 文件:
在这里插入图片描述
@ComponentScan的主要作用
将前面**@AutoConfigurationPackage** 注解解析的主程序所在包的具体位置,该注解**@ComponentScan**用于将指定包中的注解类自动装配到spring的Bean容器中。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值