SpringBoot的依赖管理和自动配置(复盘一)

发布于 2021-11-29  2.42k 次阅读


一,SpringBoot简介

一,Spring的生态圈

Spring狭义上指的是Spring FrameWork,广义上指的是整个Spring生态圈

Spring的七大应用场景:

  • Microservices:微服务开发
  • Reactive:响应式编程(用少量的CPU和内存资源构建高吞吐量的应用)
  • Cloud:分布式云开发
  • Web apps:WEB应用开发
  • Serverless:无服务开发(函数级服务开发)
  • Event Driven:事件驱动
  • Batch:批处理开发
  • ……

Spring也为我们提供了一整套开发解决方案:

  • Spring Framework:一套核心机制,IOC和AOP……
  • SpringBoot:微服务解决方案,一整套应用整合的最优解
  • SpringData:数据访问解决方案,无论是SQL数据库还NoSQL都能解决数据访问问题
  • SpringCould:解决分布式下的所有问题,比如:负载均衡,服务注册发现,网关,熔断……
  • SpringSecurity:解决应用的安全控制问题
  • SpringSeesion:解决分布式情况下的会话问题
  • SpringAMQP:解决消息队列问题
  • SpringBatch:解决批处理应用问题
  • SpringShell:做命令行程序开发
  • SpringWeb:web开发
  • SpringWEB Flow:WEB的函数式(流式)开发

二,SpringBoot的概述

SpringBoot能快速构建出一套生产级别的Spring应用

在没有使用SpringBoot时,项目构建一般用的是SSM,它的配置相等麻烦,比如:Transaction事务配置,DisPatchServlet核心控制器配置,DataSource的配置,Mybatis整合配置配置,Spring和SpringMVC的整合配置,下载外部Tomcat……这些过于繁琐,而SpringBoot很好的解决这些问题

SpringBoot的两大特性:

  • 依赖管理
  • 自动配置

SpringBoot的优点:

  1. 可以很简单的构建一套独立的Spring应用
  2. 内嵌了web服务器
  3. 自动Starter场景启动器,简化构建配置
  4. 自动配置Spring以及第三方功能
  5. 提供了生产级别的监控,健康检查及外部化配置
  6. 无代码生成,无需编写XML

SpringBoot的缺点:

  • 版本迭代较快,需要不到的关注版本变化,不同的主动性学习
  • 封装较深,内部原理复杂,不容易精通

三,SpringBoot官方文档的使用

SpringBoot官方文档的地址:https://spring.io/

Spring文档类型:

文档目录结构:

四,SpringBoot的入门

SpringBoot的使用步骤:

  • 创建Maven工程
  • 引入POM依赖
  • 创建主程序
  • 编写业务类
  • 测试
  • 简化配置
  • 简化部署

① 创建Maven工程(略)

② 映入POM依赖

SpringBoot的pom依赖主要由两部分组成:

  • parent父工程
  • starter场景启动器
<!--SpringBoot父工程-->  
  <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.0</version>
  </parent>

<dependencies>

    <!--web场景启动器,不需要声明版本,所有启动器的版本号和父工程一样-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

③ 创建主程序

//@SpringBootApplication标记为主程序类,固定写法
@SpringBootApplication
public class springbootapplication {

    public static void main(String[] args) {
        SpringApplication.run(springbootapplication.class,args);
    }
}

④ 编写业务类

@Controller
public class json_control {

    @ResponseBody
    @RequestMapping("/home")
    public String json(){


        return "SpringBoot 启动成功!";
    }
}

⑤ 测试(启动主程序并访问)

⑥ 简化配置

SpringBoot的所有配置只需在一个文件中指定(.properties,.yml),不像SSM需要各种xml配置
#例:修改springboot启动的端口号
server.port=8888

⑦ 简化部署(可执行Jar包)

SpringBoot内嵌了一个Tomcat,打成的Jar包有一整套运行环境,不需要将程序单独打成jar或者war包,放在外部web服务器上运行,可以直接运行jar即可访问

打包插件:

<!--添加SpringBoot打包插件,这样打出来的jar才是可执行的,不然会报没有主清单属性的错误-->
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

运行jar包:

java -jar jar包路径

二,SpringBoot依赖管理

SpringBoot的依赖管理包含四大部分:

  1. 依赖管理
  2. starter场景启动器
  3. 自动版本仲裁
  4. 可以修改版本号

SpringBoot依赖管理的实现依赖于Maven的继承,它的所有依赖管理,版本仲裁,场景启动器都基于Maven的继承关系

在Maven继承有两个部分:SpringBoot也是基于这两点实现的

  1. 在父工程中声明要被继承的依赖
  2. 在子工程中通过parent继承父工程中的依赖

一,SpringBoot父工程的源文件

在SpringBoot中父工程的定义以及被封装好了,直接通过中央的maven仓库下载到本地即可,不需要自己定义或者配置

源文件主要包含四个部分:

  • 项目描述
  • 公共属性
  • 声明被继承依赖
  • 声明被继承插件

这个SpringBoot的maven父工程spring-boot-dependencies源文件(因为太多了重复的有删减)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-dependencies</artifactId>
  <version>2.5.0</version>
    <!--打包类型,pom为父工程-->
  <packaging>pom</packaging>
    <!--项目的名称-->
  <name>spring-boot-dependencies</name>
    <!--项目的描述信息,在生产项目文档时有用-->
  <description>Spring Boot Dependencies</description>
    <!--哪个网站可以找到这个项目,提示如果 Maven 资源列表没有,可以直接上该网站寻找, Maven 产生的文档用-->
  <url>https://spring.io/projects/spring-boot</url>
    <!--该元素描述了项目所有License列表-->
  <licenses>
    <!--描述了项目的license,用于生成项目的web站点的license页面,其他一些报表和validation也会用到该元素-->
    <license>
        <!--license用于法律上的名称-->
      <name>Apache License, Version 2.0</name>
         <!--官方的license正文页面的URL-->
      <url>https://www.apache.org/licenses/LICENSE-2.0</url>
    </license>
  </licenses>
    <!--开发者信息,下面可以描述N个开发者-->
  <developers>
    <!--具体开发信息-->
    <developer>
        <!--开发者姓名-->
      <name>Pivotal</name>
        <!--开发者邮箱-->
      <email>info@pivotal.io</email>
        <!--项目开发者所属组织-->
      <organization>Pivotal Software, Inc.</organization>
         <!--项目开发者所属组织的URL-->
      <organizationUrl>https://www.spring.io</organizationUrl>
    </developer>
  </developers>
    <!--声明项目资源存放-->
  <scm>
    <!--项目资源存放地址,这里是github-->
    <url>https://github.com/spring-projects/spring-boot</url>
  </scm>
    
<!--定义maven公共属性,这些属性可以在该文件任何地方被调用,主要是封装了各个依赖版本号-->
  <properties>
    <activemq.version>5.16.2</activemq.version>
    <antlr2.version>2.7.7</antlr2.version>
    <appengine-sdk.version>1.9.88</appengine-sdk.version>
    <artemis.version>2.17.0</artemis.version>
    <aspectj.version>1.9.6</aspectj.version>
    <jaybird.version>4.0.3.java8</jaybird.version>
    <jboss-logging.version>3.4.1.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.0</jedis.version>
  </properties>
  
     <!--dependencyManagement定义需要被继承的依赖-->
    <dependencyManagement>
    <!--依赖项,下面可以包含N个具体依赖-->
    <dependencies>
        <!--具体的依赖,版本都是通过${}调用属性值-->
      <dependency>
        <groupId>org.apache.activemq</groupId>
        <artifactId>activemq-blueprint</artifactId>
        <version>${activemq.version}</version>
      </dependency>
      <dependency>
        <groupId>org.apache.activemq</groupId>
        <artifactId>activemq-console</artifactId>
        <version>${activemq.version}</version>
        <!--exclusions声明排除依赖,这个这个排除的依赖部分不好被子工程继承-->
        <exclusions>
            <!--具体的排除依赖-->
          <exclusion>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
          </exclusion>
        </exclusions>
      </dependency>
      </dependencies>
        </dependencyManagement>

<!--构建-->
 <build>
    <!--pluginManagement声明需要继承的插件-->
    <pluginManagement>
        <!--插件项,可以包含N个具体插件-->
      <plugins>
        <!--具体的插件-->
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-failsafe-plugin</artifactId>
          <version>${maven-failsafe-plugin.version}</version>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-help-plugin</artifactId>
          <version>${maven-help-plugin.version}</version>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-install-plugin</artifactId>
          <version>${maven-install-plugin.version}</version>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-invoker-plugin</artifactId>
          <version>${maven-invoker-plugin.version}</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

二,子工程继承父工程

子工程通过Parent继承父工程的依赖和插件等信息

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.5.0</version>
</parent>

继承父工程后,子工程引用父工程中的依赖时,不需要加版本号,默认使用父工程的版本号

自定义版本:因为在源父工程中通过properties属性封装了各个依赖的版本,自定义时,只需要重写属性即可

注:重写版本号时,必须属性名跟父工程的属性名一致

例:修改子工程中lombok的版本

<?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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>SpringBoot-dome</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.0</version>
    </parent>

    <properties>
                <!----重写父工程中的属性,属性名称一定要跟父工程的一致,否则重写失败>
        <lombok.version>1.15.1</lombok.version>
    </properties>

<dependencies>

    <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    </dependency>

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

</dependencies>
</project>

三,SpringBoot的Starter场景启动器

Starter是一个很实用的功能,它底层就是一种简单的封装,把每一个场景所需要的组件都封装在一起,构成场景启动器,这样解决了原始SMM项目导入依赖时的麻烦问题

场景启动器的作用:解决了导入依赖时的繁琐细节,比如依赖包需要单个导入,包版本冲突等

例:以spring-boot-starter-web启动器为例

① 这个启动器源码文件又封装了json,tomcat,spring-boot场景启动器和spring-web和spring-webmvc依赖(源码的头文件和描述文件被我删减了)

<dependencies>
    <!--Spring-boot场景启动器-->
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <version>2.5.0</version>
    <scope>compile</scope>
  </dependency>

    <!--json场景启动器-->
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-json</artifactId>
    <version>2.5.0</version>
    <scope>compile</scope>
  </dependency>

    <!--tomcat场景启动器-->
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <version>2.5.0</version>
    <scope>compile</scope>
  </dependency>

    <!--spring-web依赖-->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.3.7</version>
    <scope>compile</scope>
  </dependency>
    
    <!--spring-webmvc依赖-->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.3.7</version>
    <scope>compile</scope>
  </dependency>
</dependencies>

② 在进入spring-boot-starter-tomcat启动器看它的源文件(源码的头文件和描述文件被我删减了)

这个启动器包含各个依赖组件:tomcat-embed-core,tomcat-embed-el,tomcat-embed-websocket,org.apache.tomcat

<dependencies>
  <dependency>
    <groupId>jakarta.annotation</groupId>
    <artifactId>jakarta.annotation-api</artifactId>
    <version>1.3.5</version>
    <scope>compile</scope>
  </dependency>
  <dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-core</artifactId>
    <version>9.0.46</version>
    <scope>compile</scope>
    <exclusions>
      <exclusion>
        <artifactId>tomcat-annotations-api</artifactId>
        <groupId>org.apache.tomcat</groupId>
      </exclusion>
    </exclusions>
  </dependency>
  <dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-el</artifactId>
    <version>9.0.46</version>
    <scope>compile</scope>
  </dependency>
  <dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-websocket</artifactId>
    <version>9.0.46</version>
    <scope>compile</scope>
    <exclusions>
      <exclusion>
        <artifactId>tomcat-annotations-api</artifactId>
        <groupId>org.apache.tomcat</groupId>
      </exclusion>
    </exclusions>
  </dependency>
</dependencies>

③ 整体封装的结构(通过IDEA的Diagrams看它的封装关系图)

三,SpringBoot的自动配置

一,SpringBoot自动配置的简单概述

SpringBoot是相比较于传统Spring和SpringMVC最大的一个亮点,它可以自动配置组件,不需要手动加入容器

以SpringMVC组件为例的自动配置过程:

1,导入web场景启动器,映入全部web依赖包括SpringMVC

2,自动配置SpringMVC

  • 引入SpringMVC全部组件
  • 自动配置好SpringMVC常用组件

3,自动配置web常用功能,如:编解码

  • SpringBoot帮我们配置好了所有web开发的场景

4,默认包结构

  • 默认主程序所在的包下面的所有子包都被扫描,无需手动配置以前@ComponentScan包扫描
  • 也可以改变默认的扫描路径通过@SpringBootApplication(scanBasePackages="包的位置扫描",scanBasePackageClasses="类的位置扫描")的两个参数进行指定

5,各种配置拥有默认值

  • 默认配置最终都有对应的映射文件
  • 配置文件的值最终会绑定每一个类中,这个类会在容器中创建对象

6,按需加载所有配置项

  • SpringBoot有非常多的starter场景启动器
  • 默认引入了哪些场景,自动配置才会开启
  • SpringBoot所有的自动配置功能都在spring-boot-autoconfigure包
  • 通过@ConditionalOnClass,@ConditionalOnBean等注解判断是否开启配置

二,SpringBoot自动配置底层实现

一,SpringBoot自动配置的核心注解和底层实现

@SpringBootApplication:这个注解是SpringBoot中最根本的注解,他实现了自动配置等功能,它是个组合注解,底层有三个注解共同实现

1,SpringBootApplication的组合注解:

  • @SpringBootConfiguration:标明为SpringBoot配置类
  • @EnableAutoConfiguration:
  • @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) }):包扫描,并指定了两个自定义过滤器
@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 {……}

2,SpringBootConfiguration的底层注解:

  • @Configuration:标注表明是一个配置类
  • @Indexed: 它可以为 Spring 的模式注解添加索引,以提升应用启动性能
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
@Indexed
public @interface SpringBootConfiguration {
    @AliasFor(
        annotation = Configuration.class
    )
    boolean proxyBeanMethods() default true;
}

3,EnableAutoConfiguration的底层注解:

  • @AutoConfigurationPackage:自动配置包,底层是@import注解
  • @Import(AutoConfigurationImportSelector.class):导入AutoConfigurationImportSelector.class类

4,AutoConfigurationPackage注解的底层实现:

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

AutoConfigurationPackages.Registrar.class类的作用

作用:利用Registrar批量给容器中导入组件

源码:

static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {

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

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

new PackageImports(metadata).getPackageNames().toArray(new String[0])):获取当前启动类的包名并把当前的子包名保持导数组中,进行子包批量导入

5,AutoConfigurationImportSelector.class类

  • 利用getAutoConfigurationEntry(AnnotationMetadata annotationMetadata)方法给容器中批量导入组件
  • 使用List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes)获取需要导入的组件路径名
  • 利用工厂加载List<String> configurations = SpringFactoriesLoader.loadFactoryNames得到所有组件
  • 从META-INF/spring.factories位置加载一个文件,默认扫描我们当前系统里面所有META-INF/spring.factories位置的文件

注:在spring-boot-autoconfigure-2.3.4.RELEASE.jar包里面有主要加载路径META-INF/spring.factories文件,并不是所有的jar包都有META-INF/spring.factories

默认加载的META-INF/spring.factories文件,这里面的场景路径在springboot启动时全部会被加载(131个)

org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener
org.springframework.context.ApplicationListener=\
org.springframework.boot.autoconfigure.BackgroundPreinitializer
org.springframework.boot.env.EnvironmentPostProcessor=\
org.springframework.boot.autoconfigure.integration.IntegrationPropertiesEnvironmentPostProcessor
org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\
org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener
org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\
org.springframework.boot.autoconfigure.condition.OnBeanCondition,\
org.springframework.boot.autoconfigure.condition.OnClassCondition,\
org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration,\
org.springframework.boot.autoconfigure.netty.NettyAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
……………………………………………………………………………………

二,按需配置

在SpringBoot默认会加载两个地方的文件:

  • 当前包路路径下的所有子包或者指定CompentScan扫描路径下的包
  • 批量导入META-INF/spring.factories文件中的所有场景的自动配置(131个自动配置)

虽然在springboot基本上导入了所有配置,但它有一个开启策略,系统组件只有被开启了才能使用,它使用@Conditiona作为底层注解按条件激活加载组件

常见的按需配置加载注解:

  • @ConditionalOnClass(value=):是否有该类,包含了才开启
  • @ConditionalOnBean():容器中是否包含该类型的组件
  • @ConditionalOnMissingBean(value=):容器是否不包含该类
  • @ConditionalOnProperty():在Spring配置文件中是否配置
  • ……

如:

@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "spring.batch.job", name = "enabled", havingValue = "true", matchIfMissing = true)
public JobLauncherApplicationRunner jobLauncherApplicationRunner(JobLauncher jobLauncher, JobExplorer jobExplorer,
      JobRepository jobRepository, BatchProperties properties) {
   JobLauncherApplicationRunner runner = new JobLauncherApplicationRunner(jobLauncher, jobExplorer, jobRepository);
   String jobNames = properties.getJob().getNames();
   if (StringUtils.hasText(jobNames)) {
      runner.setJobNames(jobNames);
   }
   return runner;
}
  • SpringBoot先加载所有的自动配置类,SpringBoot默认启动时就加载了所有的自动配置类
  • 每个自动配置类按照条件进行生效,默认都会绑定配置文件指定的值,xxxxproperties里面拿,xxxproperties和配置文件进行绑定
  • 生效的配置类就会给容器中装配很多组件
  • 只要容器中有这些组件,相当于这些功能就有了
  • 定制化配置,用户可以自己定义替换底层的bean,用户看这个组件是获取的配置文件什么值去修改

xxxxAutoConfigation ---> 组件 ---> xxxxProperties里面拿值 ---> application.properties

@EnableConfigurationProperties(CacheProperties.class)注解将properties配置文件和类相绑定再取值

 


路漫漫其修远兮,吾将上下而求索