# SpringBoot 简介

SpringBoot 的目标是为所有 Spring 开发者提供一种快速的入门体验,开箱即用,无需编写配置文件, SpringBoot 可以快速创建一个独立的生产级别的 Spring 应用,其实 SpringBoot 底层是靠 Spring 来实现的,使用 SpringBoot 只需要编写少量配置即可快速整合 Spring 以及第三方技术支持。

# SpringBoot 特性

  • 可以快速创建独立的 Spring 应用。
    • SSM :导包、编写配置、启动运行。
  • 直接嵌入 TomcatJettyUndertowServlet 容器,无需部署 war 包。
  • 提供可选的 starter 来简化应用之间的整合,如: web-starterjson-startermybatis-starter 等。
  • 按需自动配置 Spring 以及第三方库:
    • 约定大于配置,每个场景都有很多默认配置。
    • 如果需要使用这些场景,这个场景的所有配置都会自动配置好。
  • 提供生产级特性如:监控指标、健康检查 (k8s) 、外部化配置等。
  • 无代码生成,无 xml , 配置文件可以使用 propertiesymalyml

# 系统环境最低要求

SpringBoot3.0 最低需求为 Java 17 并且还需要 SpringFramework 6.0.0-M2 及以上版本。

构建工具版本
Gradle7.4+
Maven3.5+

开发工具建议使用 IntelliJ IDEA 2021.2.1 及更高版本。

工具 & 环境版本
Java17+
IDEA2021.2.1+

SpringBoot 支持以下嵌入式 servlet 容器:

容器名称Servlet 版本
Tomcat 10.05.0
Jetty5.1
Undertow 2.25.1

# SpringBoot 快速体验

1️⃣ 创建项目或模块,选择 Spring Initializr , Java 版本最低要求为 17

pFFO2k9.png

2️⃣ 选择 SpringBoot 的版本,以及 SpringWeb 依赖。

pFFOWf1.png

3️⃣ 目录结构如下:

pFFOhSx.png

4️⃣ pom.xml 文件解析:

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <!-- 引入 Spring Boot3.x 父项目 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.1</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>top.rem.rain</groupId>
    <artifactId>springboot3-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot3-demo</name>
    <description>springboot3-demo</description>
    <properties>
        <!--Java Jdk 版本要求 17 及以上 -->
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <!-- 引入 spring-boot-starter-web, 支持 web 开发 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- 引入单元测试 starter-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <!--SpringBoot maven 插件,支持 maven 的全流程命令以及程序运行 -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

5️⃣ 在 application.properties 配置文件中指定端口。

application.properties
#应用启动端口
server.port=8080

6️⃣ 编写一个 Controller 类。

package top.rem.rain.springboot3demo;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class Controller {
    @RequestMapping("/spring")
    public String getSpring() {
        return "hello,my is SpringBoot3.x";
    }
}

7️⃣ 启动应用。

pFFOjpt.png

8️⃣ 使用浏览器访问 http://localhost:8080/spring , 接口结果如下:

pFFOv1P.png

# SpringBoot 依赖管理机制

  1. 为什么导入 spring-boot-starter-web 所有相关依赖都导入了进来?
    1. 开发什么场景,导入什么场景启动器。
    2. 导入场景启动器,场景启动器会自动把这个场景的所有核心依赖全部导入进来。
  2. 为什么不需要写版本号?
    1. 每个 boot 项目都有一个父项目 spring-boot-starter-parent
    2. parent 的父项目是 spring-boot-dependencies
    3. 父项目版本仲裁中心, Spring 官方已经把常见 jar 的依赖版本都做好了声明。
    spring-boot-dependencies-3.2.1.pom.xml
    <?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 https://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>3.2.1</version>
      <packaging>pom</packaging>
      <name>spring-boot-dependencies</name>
      <description>Spring Boot Dependencies</description>
      <url>https://spring.io/projects/spring-boot</url>
      <licenses>
        <license>
          <name>Apache License, Version 2.0</name>
          <url>https://www.apache.org/licenses/LICENSE-2.0</url>
        </license>
      </licenses>
      <developers>
        <developer>
          <name>Spring</name>
          <email>ask@spring.io</email>
          <organization>VMware, Inc.</organization>
          <organizationUrl>https://www.spring.io</organizationUrl>
        </developer>
      </developers>
      <scm>
        <url>https://github.com/spring-projects/spring-boot</url>
      </scm>
      <properties>
        <activemq.version>5.18.3</activemq.version>
        <angus-mail.version>2.0.2</angus-mail.version>
        <artemis.version>2.31.2</artemis.version>
        <aspectj.version>1.9.21</aspectj.version>
        <assertj.version>3.24.2</assertj.version>
        <awaitility.version>4.2.0</awaitility.version>
        <brave.version>5.16.0</brave.version>
        <build-helper-maven-plugin.version>3.4.0</build-helper-maven-plugin.version>
        <byte-buddy.version>1.14.10</byte-buddy.version>
        <cache2k.version>2.6.1.Final</cache2k.version>
        <caffeine.version>3.1.8</caffeine.version>
        <cassandra-driver.version>4.17.0</cassandra-driver.version>
        <classmate.version>1.6.0</classmate.version>
        <commons-codec.version>1.16.0</commons-codec.version>
        <commons-dbcp2.version>2.10.0</commons-dbcp2.version>
        <commons-lang3.version>3.13.0</commons-lang3.version>
        <commons-pool.version>1.6</commons-pool.version>
        <commons-pool2.version>2.12.0</commons-pool2.version>
        //..........配置太多此处省略,只展示一部分,知道这个事就可以
      </properties>
      <dependencyManagement>
        <dependencies>
          //.........
        </dependencies>
      </dependencyManagement>
      <build>
        <pluginManagement>
          <plugins>
            //.........
          </plugins>
        </pluginManagement>
      </build>
    </project>
  3. 第三方 jar 包。
    1. 父项目中没有进行管理的自行声明即可。
    <dependency>
        <groupId>com.alibaba.fastjson2</groupId>
        <artifactId>fastjson2</artifactId>
        <version>2.0.25</version>
    </dependency>

# SpringBoot 自动配置机制

# 初步理解

  1. 自动配置 TomcatSpringMVC 等。
    1. 导入场景后容器就会自动配置好这个场景的核心组件。
    2. 之前需要自己手动去写 DispatcherServletViewResolver 等配置,现在这些配置已经自动配置好了,容器中有了什么组件就具备什么功能。
    Springboot3DemoApplication.java
    package top.rem.rain.springboot3demo;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    @SpringBootApplication
    public class Springboot3DemoApplication {
        public static void main(String[] args) {
            // 1. 局部变量类型的自动推断
            var ioc = SpringApplication.run(Springboot3DemoApplication.class, args);
            // 2. 获取容器中所有组件的名字
            String[] names = ioc.getBeanDefinitionNames();
            // 3. 挨个遍历:
            // dispatcherServlet、beanNameViewResolver、characterEncodingFilter、multipartResolver
            // SpringBoot 把以前配置的核心组件现在都给我们自动配置好了。
            for (String name : names) {
                System.out.println(name);
            }
        }
    }
    1. 执行结果如下:
    执行结果
    C:\LightRainData\IDEA\JDK\JDK-17.0.6\bin\java.exe -XX:TieredStopAtLevel=1 -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote -Dspring.jmx.enabled=true -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true "-Dmanagement.endpoints.jmx.exposure.include=*" "-javaagent:C:\LightRainData\IDEA\IntelliJ IDEA 2022.3.2\lib\idea_rt.jar=1541:C:\LightRainData\IDEA\IntelliJ IDEA 2022.3.2\bin" -Dfile.encoding=UTF-8 -classpath D:\ 项目 \gitee\springboot3-demo\target\classes;C:\Users\LightRain\.m2\repository\org\springframework\boot\spring-boot-starter-web\3.2.1\spring-boot-starter-web-3.2.1.jar;C:\Users\LightRain\.m2\repository\org\springframework\boot\spring-boot-starter\3.2.1\spring-boot-starter-3.2.1.jar;C:\Users\LightRain\.m2\repository\org\springframework\boot\spring-boot\3.2.1\spring-boot-3.2.1.jar;C:\Users\LightRain\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\3.2.1\spring-boot-autoconfigure-3.2.1.jar;C:\Users\LightRain\.m2\repository\org\springframework\boot\spring-boot-starter-logging\3.2.1\spring-boot-starter-logging-3.2.1.jar;C:\Users\LightRain\.m2\repository\ch\qos\logback\logback-classic\1.4.14\logback-classic-1.4.14.jar;C:\Users\LightRain\.m2\repository\ch\qos\logback\logback-core\1.4.14\logback-core-1.4.14.jar;C:\Users\LightRain\.m2\repository\org\apache\logging\log4j\log4j-to-slf4j\2.21.1\log4j-to-slf4j-2.21.1.jar;C:\Users\LightRain\.m2\repository\org\apache\logging\log4j\log4j-api\2.21.1\log4j-api-2.21.1.jar;C:\Users\LightRain\.m2\repository\org\slf4j\jul-to-slf4j\2.0.9\jul-to-slf4j-2.0.9.jar;C:\Users\LightRain\.m2\repository\jakarta\annotation\jakarta.annotation-api\2.1.1\jakarta.annotation-api-2.1.1.jar;C:\Users\LightRain\.m2\repository\org\yaml\snakeyaml\2.2\snakeyaml-2.2.jar;C:\Users\LightRain\.m2\repository\org\springframework\boot\spring-boot-starter-json\3.2.1\spring-boot-starter-json-3.2.1.jar;C:\Users\LightRain\.m2\repository\com\fasterxml\jackson\core\jackson-databind\2.15.3\jackson-databind-2.15.3.jar;C:\Users\LightRain\.m2\repository\com\fasterxml\jackson\core\jackson-annotations\2.15.3\jackson-annotations-2.15.3.jar;C:\Users\LightRain\.m2\repository\com\fasterxml\jackson\core\jackson-core\2.15.3\jackson-core-2.15.3.jar;C:\Users\LightRain\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.15.3\jackson-datatype-jdk8-2.15.3.jar;C:\Users\LightRain\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.15.3\jackson-datatype-jsr310-2.15.3.jar;C:\Users\LightRain\.m2\repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.15.3\jackson-module-parameter-names-2.15.3.jar;C:\Users\LightRain\.m2\repository\org\springframework\boot\spring-boot-starter-tomcat\3.2.1\spring-boot-starter-tomcat-3.2.1.jar;C:\Users\LightRain\.m2\repository\org\apache\tomcat\embed\tomcat-embed-core\10.1.17\tomcat-embed-core-10.1.17.jar;C:\Users\LightRain\.m2\repository\org\apache\tomcat\embed\tomcat-embed-el\10.1.17\tomcat-embed-el-10.1.17.jar;C:\Users\LightRain\.m2\repository\org\apache\tomcat\embed\tomcat-embed-websocket\10.1.17\tomcat-embed-websocket-10.1.17.jar;C:\Users\LightRain\.m2\repository\org\springframework\spring-web\6.1.2\spring-web-6.1.2.jar;C:\Users\LightRain\.m2\repository\org\springframework\spring-beans\6.1.2\spring-beans-6.1.2.jar;C:\Users\LightRain\.m2\repository\io\micrometer\micrometer-observation\1.12.1\micrometer-observation-1.12.1.jar;C:\Users\LightRain\.m2\repository\io\micrometer\micrometer-commons\1.12.1\micrometer-commons-1.12.1.jar;C:\Users\LightRain\.m2\repository\org\springframework\spring-webmvc\6.1.2\spring-webmvc-6.1.2.jar;C:\Users\LightRain\.m2\repository\org\springframework\spring-aop\6.1.2\spring-aop-6.1.2.jar;C:\Users\LightRain\.m2\repository\org\springframework\spring-context\6.1.2\spring-context-6.1.2.jar;C:\Users\LightRain\.m2\repository\org\springframework\spring-expression\6.1.2\spring-expression-6.1.2.jar;C:\Users\LightRain\.m2\repository\org\slf4j\slf4j-api\2.0.9\slf4j-api-2.0.9.jar;C:\Users\LightRain\.m2\repository\org\springframework\spring-core\6.1.2\spring-core-6.1.2.jar;C:\Users\LightRain\.m2\repository\org\springframework\spring-jcl\6.1.2\spring-jcl-6.1.2.jar top.rem.rain.springboot3demo.Springboot3DemoApplication
      .   ____          _            __ _ _
     /\\ /___'_ __ _ _(_)_ __  __ _ \ \ \ \
    ( ( )\___ | '_ | '_| | '_ \/_` | \ \ \ \
     \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
      '  |____| .__|_| |_|_| |_\__, | ////
     =========|_|==============|___/=/_/_/_/
     :: Spring Boot ::                (v3.2.1)
    2024-01-17T03:42:52.148+08:00  INFO 75548 --- [           main] t.r.r.s.Springboot3DemoApplication       : Starting Springboot3DemoApplication using Java 17.0.6 with PID 75548 (D:\ 项目 \gitee\springboot3-demo\target\classes started by LightRain in D:\ 项目 \gitee\springboot3-demo)
    2024-01-17T03:42:52.150+08:00  INFO 75548 --- [           main] t.r.r.s.Springboot3DemoApplication       : No active profile set, falling back to 1 default profile: "default"
    2024-01-17T03:42:52.721+08:00  INFO 75548 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
    2024-01-17T03:42:52.730+08:00  INFO 75548 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
    2024-01-17T03:42:52.730+08:00  INFO 75548 --- [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.17]
    2024-01-17T03:42:52.780+08:00  INFO 75548 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
    2024-01-17T03:42:52.780+08:00  INFO 75548 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 595 ms
    2024-01-17T03:42:53.009+08:00  INFO 75548 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path ''
    2024-01-17T03:42:53.015+08:00  INFO 75548 --- [           main] t.r.r.s.Springboot3DemoApplication       : Started Springboot3DemoApplication in 1.127 seconds (process running for 1.617)
    org.springframework.context.annotation.internalConfigurationAnnotationProcessor
    org.springframework.context.annotation.internalAutowiredAnnotationProcessor
    org.springframework.context.annotation.internalCommonAnnotationProcessor
    org.springframework.context.event.internalEventListenerProcessor
    org.springframework.context.event.internalEventListenerFactory
    springboot3DemoApplication
    org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory
    controller
    org.springframework.boot.autoconfigure.AutoConfigurationPackages
    org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration
    propertySourcesPlaceholderConfigurer
    org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration
    fileWatcher
    sslPropertiesSslBundleRegistrar
    sslBundleRegistry
    org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor
    org.springframework.boot.context.internalConfigurationPropertiesBinder
    org.springframework.boot.context.properties.BoundConfigurationProperties
    org.springframework.boot.context.properties.EnableConfigurationPropertiesRegistrar.methodValidationExcludeFilter
    spring.ssl-org.springframework.boot.autoconfigure.ssl.SslProperties
    org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration$TomcatWebSocketConfiguration
    websocketServletWebServerCustomizer
    org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration
    org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryConfiguration$EmbeddedTomcat
    tomcatServletWebServerFactory
    org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration
    servletWebServerFactoryCustomizer
    tomcatServletWebServerFactoryCustomizer
    server-org.springframework.boot.autoconfigure.web.ServerProperties
    webServerFactoryCustomizerBeanPostProcessor
    errorPageRegistrarBeanPostProcessor
    org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration$DispatcherServletConfiguration
    dispatcherServlet
    spring.mvc-org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties
    org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration$DispatcherServletRegistrationConfiguration
    dispatcherServletRegistration
    org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration
    org.springframework.boot.autoconfigure.task.TaskExecutorConfigurations$ThreadPoolTaskExecutorBuilderConfiguration
    threadPoolTaskExecutorBuilder
    org.springframework.boot.autoconfigure.task.TaskExecutorConfigurations$TaskExecutorBuilderConfiguration
    taskExecutorBuilder
    org.springframework.boot.autoconfigure.task.TaskExecutorConfigurations$SimpleAsyncTaskExecutorBuilderConfiguration
    simpleAsyncTaskExecutorBuilder
    org.springframework.boot.autoconfigure.task.TaskExecutorConfigurations$TaskExecutorConfiguration
    applicationTaskExecutor
    org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration
    spring.task.execution-org.springframework.boot.autoconfigure.task.TaskExecutionProperties
    org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration
    error
    beanNameViewResolver
    org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration$DefaultErrorViewResolverConfiguration
    conventionErrorViewResolver
    spring.web-org.springframework.boot.autoconfigure.web.WebProperties
    org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration
    errorAttributes
    basicErrorController
    errorPageCustomizer
    preserveErrorControllerTargetClassPostProcessor
    org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$EnableWebMvcConfiguration
    welcomePageHandlerMapping
    welcomePageNotAcceptableHandlerMapping
    localeResolver
    themeResolver
    flashMapManager
    mvcConversionService
    mvcValidator
    mvcContentNegotiationManager
    requestMappingHandlerMapping
    mvcPatternParser
    mvcUrlPathHelper
    mvcPathMatcher
    viewControllerHandlerMapping
    beanNameHandlerMapping
    routerFunctionMapping
    resourceHandlerMapping
    mvcResourceUrlProvider
    defaultServletHandlerMapping
    requestMappingHandlerAdapter
    handlerFunctionAdapter
    mvcUriComponentsContributor
    httpRequestHandlerAdapter
    simpleControllerHandlerAdapter
    handlerExceptionResolver
    mvcViewResolver
    mvcHandlerMappingIntrospector
    viewNameTranslator
    org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter
    defaultViewResolver
    viewResolver
    requestContextFilter
    org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
    formContentFilter
    org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration
    mbeanExporter
    objectNamingStrategy
    mbeanServer
    spring.jmx-org.springframework.boot.autoconfigure.jmx.JmxProperties
    org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration
    springApplicationAdminRegistrar
    org.springframework.boot.autoconfigure.aop.AopAutoConfiguration$ClassProxyingConfiguration
    forceAutoProxyCreatorToUseClassProxying
    org.springframework.boot.autoconfigure.aop.AopAutoConfiguration
    org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration
    applicationAvailability
    org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$Jackson2ObjectMapperBuilderCustomizerConfiguration
    standardJacksonObjectMapperBuilderCustomizer
    spring.jackson-org.springframework.boot.autoconfigure.jackson.JacksonProperties
    org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$JacksonObjectMapperBuilderConfiguration
    jacksonObjectMapperBuilder
    org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$ParameterNamesModuleConfiguration
    parameterNamesModule
    org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$JacksonObjectMapperConfiguration
    jacksonObjectMapper
    org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$JacksonMixinConfiguration
    jsonMixinModuleEntries
    jsonMixinModule
    org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration
    jsonComponentModule
    org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration
    org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration
    lifecycleProcessor
    spring.lifecycle-org.springframework.boot.autoconfigure.context.LifecycleProperties
    org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration$StringHttpMessageConverterConfiguration
    stringHttpMessageConverter
    org.springframework.boot.autoconfigure.http.JacksonHttpMessageConvertersConfiguration$MappingJackson2HttpMessageConverterConfiguration
    mappingJackson2HttpMessageConverter
    org.springframework.boot.autoconfigure.http.JacksonHttpMessageConvertersConfiguration
    org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration
    messageConverters
    org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration
    spring.info-org.springframework.boot.autoconfigure.info.ProjectInfoProperties
    org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration
    spring.sql.init-org.springframework.boot.autoconfigure.sql.init.SqlInitializationProperties
    org.springframework.boot.sql.init.dependency.DatabaseInitializationDependencyConfigurer$DependsOnDatabaseInitializationPostProcessor
    org.springframework.boot.autoconfigure.task.TaskSchedulingConfigurations$ThreadPoolTaskSchedulerBuilderConfiguration
    threadPoolTaskSchedulerBuilder
    org.springframework.boot.autoconfigure.task.TaskSchedulingConfigurations$TaskSchedulerBuilderConfiguration
    taskSchedulerBuilder
    org.springframework.boot.autoconfigure.task.TaskSchedulingConfigurations$SimpleAsyncTaskSchedulerBuilderConfiguration
    simpleAsyncTaskSchedulerBuilder
    org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration
    spring.task.scheduling-org.springframework.boot.autoconfigure.task.TaskSchedulingProperties
    org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration
    httpMessageConvertersRestClientCustomizer
    restClientSsl
    restClientBuilderConfigurer
    restClientBuilder
    org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration
    restTemplateBuilderConfigurer
    restTemplateBuilder
    org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration$TomcatWebServerFactoryCustomizerConfiguration
    tomcatWebServerFactoryCustomizer
    org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration
    org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration
    characterEncodingFilter
    localeCharsetMappingsCustomizer
    org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration
    multipartConfigElement
    multipartResolver
    spring.servlet.multipart-org.springframework.boot.autoconfigure.web.servlet.MultipartProperties
    org.springframework.aop.config.internalAutoProxyCreator
  2. 默认包扫描规则
    1. @SpringBootApplication 标注的类就是主程序类。
    2. SpringBoot 只会扫描主程序所在的包及其下面的子包,自动 component-scan 功能,在主程序的包之外,哪怕写了 MVC 组件,注解也无法扫描并交由 IOC 容器来处理。
    3. 自定义扫描路径,如果非要放在默认之外,需要给注解加上内容配置。
      1. @SpringBootApplication(scanBasePackages = "top.rem.rain")
      2. @ComponentScan("top.rem.rain") 直接指定扫描的路径,这是因为上面的 @SpringBootApplication 注解包含内嵌了三个注解分别是: @SpringBootConfiguration@EnableAutoConfiguration@ComponentScan
  3. 默认配置值
    1. 配置文件的所有配置项是和某个类的对象值进行绑定的,可以在配置文件中利用 servier.port=8080 配置,然后使用 ctrl+鼠标左键 进入对应的配置类中。
    2. 绑定了配置文件中每一项值的类那就是属性类。
    3. 比如:
      1. 官方属性文档
      2. MultipartProperties 绑定了所有文件上传相关的配置。
      3. ServerProperties 绑定了所有 Tomcat 服务器有关的配置。
  4. 按需要自动加载配置。
    1. 导入场景 spring-boot-starter-web
    2. 场景启动器除了会导入相关功能依赖,还会导入一个 spring-boot-starter 它是所有 starter 的基础核心。
    3. spring-boot-starter 导入了一个 spring-boot-autoconfigure 包,这个包里面都是各种场景的 AutoConfiguration 自动配置类。
    4. 虽然全场景的自动配置都在 spring-boot-autoconfigure 这个包中,但不全是开启的,导入哪个场景就开启哪个自动配置。
  5. 总结:导入场景启动器会触发 spring-boot-autoconfigure 这个包的自动配置,在容器中就会具有相应场景的功能。

# 自动配置

  1. 导入 starter-web 后就代表导入了 web 开发场景。

    1. 场景启动器会导入相关场景的所有依赖: starter-jsonstarter-tomcatspringmvc
    2. 每个场景启动器都会引入一个 spring-boot-starter 的核心场景启动器。
    3. 核心场景启动器引入了 spring-boot-autoconfigure 包。
    4. spring-boot-autoconfigure 包里包含了所有场景的所有配置。
    5. 只要这个包下的所有类都能生效,那么就相当于 SpringBoot 官方写好的整合功能就生效。
    6. SpringBoot 默认扫不到 spring-boot-autoconfigure 下写好的所有配置类,默认只扫描主程序所在的包,但利用下面主程序的注解就做到了导入。
  2. 主程序: @SpringBootApplication 注解源码如下:

    SpringBootApplication.java
    package org.springframework.boot.autoconfigure;
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Inherited;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    import org.springframework.beans.factory.support.BeanNameGenerator;
    import org.springframework.boot.SpringBootConfiguration;
    import org.springframework.boot.context.TypeExcludeFilter;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.FilterType;
    import org.springframework.context.annotation.ComponentScan.Filter;
    import org.springframework.core.annotation.AliasFor;
    @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 {};
       @AliasFor(
               annotation = EnableAutoConfiguration.class
       )
       String[] excludeName() default {};
       @AliasFor(
               annotation = ComponentScan.class,
               attribute = "basePackages"
       )
       String[] scanBasePackages() default {};
       @AliasFor(
               annotation = ComponentScan.class,
               attribute = "basePackageClasses"
       )
       Class<?>[] scanBasePackageClasses() default {};
       @AliasFor(
               annotation = ComponentScan.class,
               attribute = "nameGenerator"
       )
       Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
       @AliasFor(
               annotation = Configuration.class
       )
       boolean proxyBeanMethods() default true;
    }
    1. @SpringBootApplication 是由三个注解组成的: SpringBootConfigurationEnableAutoConfigurationComponentScan
    2. SpringBoot 默认只扫描自己主程序所在的包及其下面的子包。
    3. @EnableAutoConfiguration 注解是 SpringBoot 开启自动配置的核心。
    EnableAutoConfiguration.java
    package org.springframework.boot.autoconfigure;
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Inherited;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    import org.springframework.context.annotation.Import;
    @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 注解, @Import 注解导入了一个 AutoConfigurationImportSelector 类,这个类的作用是批量导入组件, @Import 将指定的类或配置文件导入到当前类中,可以用于导入其它自定义类、配置文件等,但不会将其加入到 IOC 中,这个类内部的方法还获取了一些注册信息,其调试发现就是主程序所在的包路径,故帮助我们扫描主程序所在的包和子包路径下的所有组件。

@AutoConfigurationPackage 注解代表自动配置包,源码如下:

AutoConfigurationPackage.java
package org.springframework.boot.autoconfigure;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Import;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({AutoConfigurationPackages.Registrar.class})
public @interface AutoConfigurationPackage {
    String[] basePackages() default {};
    Class<?>[] basePackageClasses() default {};
}

使用 ctrl+鼠标左键 进入 AutoConfigurationImportSelector 类中找到一个名为 getAutoConfigurationEntry 的方法,利用 getAutoConfigurationEntry(annotationMetadata); 给容器中批量导入一些组件,调用 getCandidateConfigurations(annotationMetadata, attributes); 获取所有需要导入到容器中的配置类,最后使用 ImportCandidates.load(Class<?> annotation, ClassLoader classLoader) 方法得到所有组件,将会从 META-INF/spring/%s.imports 位置来加载一个文件,文件位置在 spring-boot-autoconfigure:3.2.1 版本下的 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

SpringBoot 启动时会默认加载 152 个配置类,这些配置来自于 spring-boot-autoconfigure:3.2.1 下的 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件中指定的。

org.springframework.boot.autoconfigure.AutoConfiguration.imports
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.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.data.mongo.MongoRepositoriesAutoConfiguration
org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration
org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveDataAutoConfiguration
org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveRepositoriesAutoConfiguration
org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcRepositoriesAutoConfiguration
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration
org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration
org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration
org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchClientAutoConfiguration
org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration
org.springframework.boot.autoconfigure.elasticsearch.ReactiveElasticsearchClientAutoConfiguration
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration
org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration
org.springframework.boot.autoconfigure.graphql.data.GraphQlReactiveQueryByExampleAutoConfiguration
org.springframework.boot.autoconfigure.graphql.data.GraphQlReactiveQuerydslAutoConfiguration
org.springframework.boot.autoconfigure.graphql.data.GraphQlQueryByExampleAutoConfiguration
org.springframework.boot.autoconfigure.graphql.data.GraphQlQuerydslAutoConfiguration
org.springframework.boot.autoconfigure.graphql.reactive.GraphQlWebFluxAutoConfiguration
org.springframework.boot.autoconfigure.graphql.rsocket.GraphQlRSocketAutoConfiguration
org.springframework.boot.autoconfigure.graphql.rsocket.RSocketGraphQlClientAutoConfiguration
org.springframework.boot.autoconfigure.graphql.security.GraphQlWebFluxSecurityAutoConfiguration
org.springframework.boot.autoconfigure.graphql.security.GraphQlWebMvcSecurityAutoConfiguration
org.springframework.boot.autoconfigure.graphql.servlet.GraphQlWebMvcAutoConfiguration
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration
org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration
org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration
org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration
org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration
org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration
org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration
org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration
org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration
org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
org.springframework.boot.autoconfigure.jdbc.JdbcClientAutoConfiguration
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration
org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration
org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration
org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration
org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration
org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration
org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration
org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration
org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration
org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration
org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration
org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration
org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration
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
org.springframework.boot.autoconfigure.pulsar.PulsarAutoConfiguration
org.springframework.boot.autoconfigure.pulsar.PulsarReactiveAutoConfiguration
org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration
org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration
org.springframework.boot.autoconfigure.r2dbc.R2dbcTransactionManagerAutoConfiguration
org.springframework.boot.autoconfigure.reactor.ReactorAutoConfiguration
org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration
org.springframework.boot.autoconfigure.rsocket.RSocketRequesterAutoConfiguration
org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration
org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration
org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration
org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration
org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration
org.springframework.boot.autoconfigure.security.rsocket.RSocketSecurityAutoConfiguration
org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyAutoConfiguration
org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration
org.springframework.boot.autoconfigure.session.SessionAutoConfiguration
org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration
org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration
org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration
org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration
org.springframework.boot.autoconfigure.security.oauth2.server.servlet.OAuth2AuthorizationServerAutoConfiguration
org.springframework.boot.autoconfigure.security.oauth2.server.servlet.OAuth2AuthorizationServerJwtAutoConfiguration
org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration
org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration
org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration
org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration
org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizationAutoConfiguration
org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration
org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration
org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration
org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration
org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration
org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration
org.springframework.boot.autoconfigure.web.reactive.ReactiveMultipartAutoConfiguration
org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration
org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration
org.springframework.boot.autoconfigure.web.reactive.WebSessionIdResolverAutoConfiguration
org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration
org.springframework.boot.autoconfigure.web.reactive.function.client.ClientHttpConnectorAutoConfiguration
org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
org.springframework.boot.autoconfigure.websocket.reactive.WebSocketReactiveAutoConfiguration
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration
org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration

项目启动时会利用 @Import 批量导入组件,会把 autoconfigure 包下的 xxxAutoConfiguration 类导入进来,这就是自动配置类,虽然导入了这么多配置类,这些配置类并不会都将生效,而是在每一个自动配置类中都有一个条件注解 @ConditionalOnxxx , 只有条件成立才会生效。

# 核心流程总结

  1. 导入 starter 就会导入 autoconfigure 包。
  2. autoconfigure 包下面有一个 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件,里面指定了所有启动要加载的自动配置类。
  3. @EnableAutoConfiguration 注解会自动把上面文件里面的自动配置类导入进来,根据条件注解进行按需加载。
  4. 符合条件的情况下 xxxAutoConfiguration 就会给容器中导入一堆组件,组件都是从 xxxProperties 中提取属性值, xxxProperties 和配置文件进行了绑定。

# SpringBoot 核心技能

SpringBoot 抛弃了传统的 XML 配置方式,改为全注解开发流程。

# 常用注解

🚀SpringBoot & 其它常用注解

# 组件注册

以前的步骤:通过 Spring 配置文件,进行组件注册,如果是纯 XML 配置方式还需要声明 Bean 对象,赋予唯一标识和全类名,然后通过 set 方法进行注入或其它注入方式来注入默认属性值。

现在的步骤如下:

  1. 编写一个配置类并在类上使用 @Configuration 注解进行标注,这将表示此类是 SpringBoot 的配置类,配置类也会被加入到 IOC 容器中 (可以通过 ctrl+鼠标左键 点击这个注解就可以看到里面内嵌了 @Component 注解),也可以使用 SpringBootConfiguration 注解进行标注,其本质是一样的,所以 Spring 相关的核心配置使用 SpringBoot 的,而通用配置使用默认的。
  2. 在配置类中,自定义方法配合 Bean 给容器中注册组件,如果是第三方的可以直接根据类型,写入配置类的方法,返回它的类型然后直接 return new 出来的对象。
  3. @Configuration 注解在 spring 5.2 以后多了一个 proxyBeanMethods 属性,它是 boolean 类型的属性可以设置为 truefalse , 默认值为 true (代表是否代理 Bean 方法),如果为 true 说明为代理对象调用方法,在获取这个对象的时候会从容器中检查有没有这个类对象,如果有就直接获取,没有就会创建一个类对象 (保持组件单实例),其主要用于解决组件依赖问题,当不更改这个值,组件在配置类配置依赖时可以直接通过 set 方法然后传入配置类的其它组件的注入方法 (即带有 Bean 的方法)。如果不想有这种依赖关系,可以将值设置为 false 就是轻量级模式,设置为 false 对于单个 Bean 从容器中获取多次还是单实例的,但依赖的情况下, Bean 内部其它的 Bean 就不是 IOC 容器中的那个,而是一个新 new 的。
  4. 使用 Import 注解导入第三方组件 (可以写在组件类 ( @Conponent@Controller 等) 或配置类上面,与配置类的注解放在一起),在括号中写入对应的 .class 字节码文件 (默认 value 值不用写属性,且是一个数组,可以导入多个组件到容器),也可以使用全类名,对应 name 属性,其实不管怎么样默认 IOC 容器在注入组件的 id 时扔是使用全类名。

因为在开发过程中可能会修改依赖,如果导入 IOC 的时候删掉之前一些用不到的依赖,这种情况下,本身靠字符串的全类名不会引起报错,但是使用字节码文件的时候,如果不存在这个类就会大面积报错。

# 条件注解

如果注解指定的条件成立则触发指定行为,可以写在配置类或组件注解和配置类内部的 @Bean 方法上。

  • @ConditionalOnClass :如果类路径中存在这个类则触发指定行为。
  • @ConditionalOnMissingClass :如果类路径中不存在这个类则触发执行行为。
  • @ConditionalOnBean :如果容器中存在这个 Bean 组件则触发指定行为。
  • @ConditionalOnMissingBean :如果容器中不存在这个 Bean 组件则触发指定行为。

比如:如果存在 Pet 这个类就给容器中放一个 Cat 组件并命名为 cat1 , 否则就给容器中放一个 Dog 组件并命名为 dog1

如果系统中有 cat1 这个组件就给容器中放一个 PetDetails 组件,命名为 zhangsan , 否则就命名为 lisi

自定义实现 Condition 接口并编写相应规则即可。

@ConditionalOnBean(value = 组件类型,name = 组件名字):判断容器中是否有这个类型的组件,并且名字是指定的值
@ConditionalOnRepositoryType (org.springframework.boot.autoconfigure.data)
@ConditionalOnDefaultWebSecurity (org.springframework.boot.autoconfigure.security)
@ConditionalOnSingleCandidate (org.springframework.boot.autoconfigure.condition)
@ConditionalOnWebApplication (org.springframework.boot.autoconfigure.condition)
@ConditionalOnWarDeployment (org.springframework.boot.autoconfigure.condition)
@ConditionalOnJndi (org.springframework.boot.autoconfigure.condition)
@ConditionalOnResource (org.springframework.boot.autoconfigure.condition)
@ConditionalOnExpression (org.springframework.boot.autoconfigure.condition)
@ConditionalOnClass (org.springframework.boot.autoconfigure.condition)
@ConditionalOnEnabledResourceChain (org.springframework.boot.autoconfigure.web)
@ConditionalOnMissingClass (org.springframework.boot.autoconfigure.condition)
@ConditionalOnNotWebApplication (org.springframework.boot.autoconfigure.condition)
@ConditionalOnProperty (org.springframework.boot.autoconfigure.condition)
@ConditionalOnCloudPlatform (org.springframework.boot.autoconfigure.condition)
@ConditionalOnBean (org.springframework.boot.autoconfigure.condition)
@ConditionalOnMissingBean (org.springframework.boot.autoconfigure.condition)
@ConditionalOnMissingFilterBean (org.springframework.boot.autoconfigure.web.servlet)
@Profile (org.springframework.context.annotation)
@ConditionalOnInitializedRestarter (org.springframework.boot.devtools.restart)
@ConditionalOnGraphQlSchema (org.springframework.boot.autoconfigure.graphql)
@ConditionalOnJava (org.springframework.boot.autoconfigure.condition)

# 属性绑定

  1. @ConfigurationProperties :声明组件的属性和配置文件哪些前缀开始项进行绑定,可以写在组件 Bean 上也可以写在配置类中的配置 Bean 的方法上。
    1. 将容器中任意组件 (Bean) 的属性值和配置文件的配置项的值进行绑定。
      1. 给容器中注册组件
        1. 在配置类外使用 @ConfigurationProperties 结合 @Component ,配置类内无需写任何方法。
        2. 配置类内使用 @Bean 结合 @ConfigurationProperties ,配置类外不用写任何注解。
      2. 使用 @ConfigurationProperties 声明组件和配置文件的哪些配置项进行绑定。
  2. @EnableConfigurationProperties :快速注册注解 (这是写于配置类上的注解,使用 @Import 注解导入的 Bean 不会进行属性绑定)。
    1. SpringBoot 默认只扫描自己主程序所在的包,如果导入第三方包,即使组件上标注了 @Component@ConfigurationProperties 注解也没有用,此时就可以使用这个注解快速进行属性绑定并把组件注册到 IOC 容器中。

# 冷门注解

# @Scope

@Scope 注解源码如下:

Scope.java
package org.springframework.context.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Scope {
    @AliasFor("scopeName")
    String value() default "";
    @AliasFor("value")
    String scopeName() default "";
    ScopedProxyMode proxyMode() default ScopedProxyMode.DEFAULT;
}
  • scopeName :是为了声明 Bean 的作用域,在 Spring 4.2 版本之前有两种模式分别是: singletonprototype 两种模式,在 4.2 之后新增了 web 作用域: requestsessionglobalsession
    • singleton :单例模式,即 SpringIOC 容器中只会有一个共享的 Bean 实例,这一个单一的实例会被存储到单例缓存中,当有请求或是引用时, IOC 容器都会返回存储在单例缓存中的同一个实例。
    • prototype :多实例模式,即每次客户端向容器获取 Bean 时, IOC 容器都会创建一个新实例进行返回,与单例模式不同的是在 IOC 容器启动的时候并不会创建 Bean 实例,并且在有请求创建 Bean 实例之后也不会管理该实例的生命周期,而是由客户端来处理。
    • requestweb 应用针对每一次 HTTP 请求都会创建一个新的 Bean 实例,且该实例仅在这次 HTTP 请求中有效。
    • session :针对每一个 session 都会创建一个 Bean 实例且生命周期为该 session 有效期间。
    • globalsession :仅基于 portletweb 应用才有意义,否则可以当作 session 来使用。
// 也可以直接写对应的字符串,无视大小写
@Scope(scopeName = ConfigurableBeanFactory.SCOPE_SINGLETON)
@Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Scope(scopeName = WebApplicationContext.SCOPE_REQUEST)
@Scope(scopeName = WebApplicationContext.SCOPE_SESSION)
@Scope(scopeName = "globalSession")

# ScopeProxyMode

  • proxyMode 表明了 @Scope 注解的 Bean 是否需要代理。
    • DEFAULT :它是 proxyMode 的默认值,一般情况下等同于 NO , 即不需要动态代理。
    • NO :不需要动态代理,即返回的是 Bean 实例对象。
    • INTERFACES :代理的对象是一个接口,即 @Scope 的作用对象是接口,这种情况是基于 JDK 实现的动态代理。
    • TARGET_CLASS :代理的对象是一个类,即 @Scope 的作用对象是个类,是以生成目标类扩展的方式创建代理,基于 CGLib 实现动态代理。
@Scope(proxyMode = ScopedProxyMode.DEFAULT)
@Scope(proxyMode = ScopedProxyMode.NO)
@Scope(proxyMode = ScopedProxyMode.INTERFACES)
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)

# @ComponentScan

ComponentScan.java
package org.springframework.context.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.core.annotation.AliasFor;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
    @AliasFor("basePackages")
    String[] value() default {};
    @AliasFor("value")
    String[] basePackages() default {};
    Class<?>[] basePackageClasses() default {};
    Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
    Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;
    ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;
    String resourcePattern() default "**/*.class";
    boolean useDefaultFilters() default true;
    Filter[] includeFilters() default {};
    Filter[] excludeFilters() default {};
    boolean lazyInit() default false;
    @Retention(RetentionPolicy.RUNTIME)
    @Target({})
    public @interface Filter {
        FilterType type() default FilterType.ANNOTATION;
        @AliasFor("classes")
        Class<?>[] value() default {};
        @AliasFor("value")
        Class<?>[] classes() default {};
        String[] pattern() default {};
    }
}
  • valuevalue 值对应要扫描的包名,可以是一个数组,放入要扫描的包名即可。
  • excludeFilters :可以填入一个数组,类型为 @Filter 注解的数组,可以排除要扫描的包,示例: excludeFilters = {@Filter(type = FilterType.xxxx, classes={xxx,xxx,xxx}) …}type = FilterType.ASSUGNABLE_TYPE 是按照类型排除。
  • includeFIlters :需要进行设置属性关闭默认扫描规则 useDefaultFilters = false ,用法和上面没有什么区别。

# @Lazy

可以给配置类中加载的 Bean 加上此注解,即便是单实例 Bean 也可以实现懒加载, IOC 创建时不加载,在第一次获取时才进行加载。

# @ConfigurationProperties

@ConfigurationProperties :用于将属性文件中的值绑定到一个 Java 对象上,它可以将属性文件中的多个属性值注入到一个 Java 对象中,与 @Value 注解不同的是 @ConfigurationProperties 可以将属性文件中的值注入到多个属性中。

# 自定义类型扫描

首先定义一个类实现 TypeFilter 接口并重写相应的方法,第一个参数 metadataReader :通过它可以获取正在扫描的类信息如:注解、类信息、类资源,第二个参数 metadataReaderFactory :它可以获取其它容器组件的信息,在使用的时候只需要 @Filter(type=FilterType.CUSTOM,classes={MyFilter}) 指定使用我们的过滤规则。

MyFilter.java
package top.rem.rain.springboot3demo;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;
import java.io.IOException;
/**
 * @Author: LightRain
 * @Description: 自定义类型扫描
 * @DateTime: 2024-01-26 13:59
 * @Version:1.0
 **/
public class MyFilter implements TypeFilter {
    @Override
    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
        metadataReader.getAnnotationMetadata();
        metadataReader.getClassMetadata();
        metadataReader.getResource();
        return false;
    }
}

# 自定义初始化 & 销毁 - 注解方式

  • @PostConstruct :在 Bean 创建完成并在属性赋值之后将执行初始化方法。
  • @PreDestroy :在容器销毁之前执行销毁方法。