springboot自动配置原理分析

文章目录

06、springboot的自动装配原理

6.1、问题引入:

我们ssm框架阶段,需要编写的大量的配置文件来整合springMvc和mybatis以及一些其他的插件等等,dao层,dataseorce的配置

mybatis的sqlsessionFactoryBean配置,以及自动包扫描mapper包等等,service配置事务等等,springmvc,处理器,视图解析器,乱码解决,dispatchservlet配置等等,最后部署到Tomcat上,等等,最后才可以运行,但是在springboot中我们好像啥都没有做,就是导入一个web模块的启动器,编写了一个controller而已,其他啥都没有做,就完成了项目运行,访问。

我们不免有一个疑问,springboot底层又是如替我们完成了其他操作,为我们配置好其他需要配置的呢?下面详细道来

6.2 、先了解一下IOC容器的功能

6.2.1、添加组件

1、@Configuration

类上标注这个注解表示这个类是一个springBoot的配置类,相当于ssm阶段的spring的xml配置文件,我们之前在spring配置文件中配置一个bean使用标签,但是在配置类中使用@Bean注解来配置一个bean,以方法名作为组件的id,返回类型就是组件的类型,返回值,就是组件在容器中的实例,与配置文件一样,默认为单实例(在@Configuration(proxyBeanMethods = true)情况下)。

/**
 * 外部无论对配置类总的这个组件注册方法调用多少次都是获取之前注册容器中的单实例对象
 * @Bean注解相当于xml配置文件的<bean></bean>标签,用来添加组件 以方法名作为组件的id,返回类型就是组件的类型,返回值,就是组件在容器中的实例
 * 注册组件,默认为单实例组件
 */
@Bean
public User user01() {
    return new User("zhangsan", 18);
}
  • Full模式与Lite模式

    • 示例
    • 最佳实战
      • 配置 类组件之间无依赖关系用Lite模式加速容器启动过程,减少判断
        • @Configuration(proxyBeanMethods = false)表示不开启代理对象使用Lite模式,创建多实例,跳过对springIOC容器检查是否存在此实例对象,直接创建
        • 配置 类组件之间无依赖关系用Lite模式加速容器启动过程,减少判断
      • 配置类组件之间有依赖关系,方法会被调用得到之前单实例组件,用Full模式
        • @Configuration(proxyBeanMethods = true)表示开启对象代理,使用Full模式,创建单实例,每次调用都会检查IOC中是否存在实例对象,又就是拿来用,无的话在创建
        • 配置 类组件之间有依赖关系,方法会被调用得到之前单实例组件,用Full模式
        • 解决组件依赖@Configuration(proxyBeanMethods = true)
  • @configuration默认为true
    springboot自动配置原理分析
    示例:

#############################Configuration使用示例######################################################
/**
 * 1、配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实例的
 * 2、配置类本身也是组件
 * 3、proxyBeanMethods:代理bean的方法
 *      Full(proxyBeanMethods = true)、【保证每个@Bean方法被调用多少次返回的组件都是单实例的】
 *      Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的】
 *      组件依赖必须使用Full模式默认。其他默认是否Lite模式
 *
 *
 *
 */
@Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件
public class MyConfig {

    /**
     * Full:外部无论对配置类中的这个组件注册方法调用多少次获取的都是之前注册容器中的单实例对象
     * @return
     */
    @Bean //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
    public User user01(){
        User zhangsan = new User("zhangsan", 18);
        //user组件依赖了Pet组件
        zhangsan.setPet(tomcatPet());
        return zhangsan;
    }

    @Bean("tom")
    public Pet tomcatPet(){
        return new Pet("tomcat");
    }
}


################################@Configuration测试代码如下########################################
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.atguigu.boot")
public class MainApplication {

    public static void main(String[] args) {
        //1、返回我们IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

        //2、查看容器里面的组件
        String[] names = run.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }

        //3、从容器中获取组件

        Pet tom01 = run.getBean("tom", Pet.class);

        Pet tom02 = run.getBean("tom", Pet.class);

        System.out.println("组件:"+(tom01 == tom02));


        //4、com.atguigu.boot.config.MyConfig$$EnhancerBySpringCGLIB$$51f1e1ca@1654a892
        MyConfig bean = run.getBean(MyConfig.class);
        System.out.println(bean);

        //如果@Configuration(proxyBeanMethods = true)代理对象调用方法。SpringBoot总会检查这个组件是否在容器中有。
        //保持组件单实例
        User user = bean.user01();
        User user1 = bean.user01();
        System.out.println(user == user1);


        User user01 = run.getBean("user01", User.class);
        Pet tom = run.getBean("tom", Pet.class);

        System.out.println("用户的宠物:"+(user01.getPet() == tom));
    }
}

2、@Bean,@Component、@Controller、@Service、@Repository

@Bean

// 但是在配置类中使用@Bean注解来配置一个bean,以方法名作为组件的id,返回类型就是组件的类型,返回值,就是组件在容器中的实例

@Bean
public User user01() {
    return new User("zhangsan", 18);
}

@Component表明这是一个组件(通用的一个注解),添加到IOC中

@Controller 控制层的组件注解

@Service 服务层的组件注解

@Repository层的注解

3、@ComponentScan、@Import

@ComponentSan组件扫描,可以指定扫描哪些包,扫描指定包以及子包的所有组件添加到IOC容器中去

@import:导入某个组件,默认组件名为全类名

 * 4、@Import({User.class, DBHelper.class})
 *      给容器中自动创建出这两个类型的组件、默认组件的名字就是全类名
 */
@Import({User.class, DBHelper.class})
@Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件
public class MyConfig {
}

4、@Conditional 按条件装配

@Conditional是一个父注解,他有很多实现类

ctrl+h打开继承树可以发现,根据判断条件分为很多种注解,判断是否存在指定的bean,是否存在指定的组件,是否存在指定的配置文件信息等等。。。。。。。。

条件装配:满足Conditional指定的条件,则进行组件注入,加载类上此注解的具体实现注解,只有满足条件,此类下的组件才会注册到IOC容器中,单纯的标注到方法上,满足条件此方法返回值得bean才会注册到IOC容器中。

SpringBoot底层自动装配会使用到大量的此注解以及实现注解。

这也是springBoot为啥只有导入了那个启动器,对应的配置才会自动的生效。
springboot自动配置原理分析

=====================测试条件装配==========================
@Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件
//@ConditionalOnBean(name = "tom")
@ConditionalOnMissingBean(name = "tom")
public class MyConfig {


    /**
     * Full:外部无论对配置类中的这个组件注册方法调用多少次获取的都是之前注册容器中的单实例对象
     * @return
     */

    @Bean //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
    public User user01(){
        User zhangsan = new User("zhangsan", 18);
        //user组件依赖了Pet组件
        zhangsan.setPet(tomcatPet());
        return zhangsan;
    }

    @Bean("tom22")
    public Pet tomcatPet(){
        return new Pet("tomcat");
    }
}

public static void main(String[] args) {
        //1、返回我们IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

        //2、查看容器里面的组件
        String[] names = run.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }

        boolean tom = run.containsBean("tom");
        System.out.println("容器中Tom组件:"+tom);

        boolean user01 = run.containsBean("user01");
        System.out.println("容器中user01组件:"+user01);

        boolean tom22 = run.containsBean("tom22");
        System.out.println("容器中tom22组件:"+tom22);

    }

6.2.2 、原生配置文件引入@ImportResource

就是springxml配置文件中配置的bean想转换为配置类中注册,使用@ImportResource注解,指定配置文件的地址即可

自动注册,迁移

xml配置文件

======================beans.xml=========================
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <bean id="haha" class="com.atguigu.boot.bean.User">
        <property name="name" value="zhangsan"></property>
        <property name="age" value="18"></property>
    </bean>

    <bean id="hehe" class="com.atguigu.boot.bean.Pet">
        <property name="name" value="tomcat"></property>
    </bean>
</beans>

配置类

@ImportResource("classpath:beans.xml")
public class MyConfig {}

======================测试=================
        boolean haha = run.containsBean("haha");
        boolean hehe = run.containsBean("hehe");
        System.out.println("haha:"+haha);//true
        System.out.println("hehe:"+hehe);//true

6.2.3、配置绑定(配置文件注入JavaBean属性)

1、原生的Java方式

public class getProperties {
     public static void main(String[] args) throws FileNotFoundException, IOException {
         Properties pps = new Properties();
         pps.load(new FileInputStream("a.properties"));
         Enumeration enum1 = pps.propertyNames();//得到配置文件的名字
         while(enum1.hasMoreElements()) {
             String strKey = (String) enum1.nextElement();
             String strValue = pps.getProperty(strKey);
             System.out.println(strKey + "=" + strValue);
             //封装到JavaBean。
         }
     }
 }

2、springboot注解方式

方式一:使用@Component,@ConfigurationProperties组合

使用@ConfigurationProperties注解在Javabean类上,prefix指定配置文件前缀,按照属性名一致注入属性值

/**
	方式一: 使用@Component,@ConfigurationProperties组合
 * 只有在容器中的组件,才会拥有SpringBoot提供的强大功能
 */
@Component
@ConfigurationProperties(prefix = "mycar")
public class Car {

    private String brand;
    private Integer price;

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public Integer getPrice() {
        return price;
    }

    public void setPrice(Integer price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Car{" +
                "brand='" + brand + '\'' +
                ", price=" + price +
                '}';
    }
}
方式二:@EnableConfigurationProperties + @ConfigurationProperties

@EnableConfigurationProperties开启属性配置绑定功能,标注在配置类上,value=需要开启属性注入的类.class,

eg:@EnableConfigurationProperties(Car.class),起到两个作用,一个是开启了car的属性配置绑定的功能,二是把car这个组件自动注册到容器中。

@EnableConfigurationProperties(Car.class)
//1、开启Car配置绑定功能
//2、把这个Car这个组件自动注册到容器中
public class MyConfig {
}

6.3、SpringBoot的依赖管理

打开我们创建springBoot项目的pom.xml文件有下面的写法

指定了我们的springBoot项目的父项目为哪一个,GAV信息

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.5.0</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

进入我们的springboot项目的父项目中又可以发现他也有一个父项目

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

进入这个父项目的父项目发现,是管理者所有的依赖版本号

几乎声明了所有开发中常用的依赖的版本号,自动版本仲裁机制

<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>
  <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.1</caffeine.version>
    ......................
    .................
    ..................
    ................
    几乎声明了所有开发中常用的依赖的版本号,自动版本仲裁机制
</properties>

我们在pom.xml配置文件中引入的spring-boot-starter-xxxx

会自动为我们导入此模块所有依赖

1、见到很多 spring-boot-starter-* : *就某种场景
2、只要引入starter,这个场景的所有常规需要的依赖我们都自动引入
3、SpringBoot所有支持的场景
https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-starter
4、见到的  *-spring-boot-starter: 第三方为我们提供的简化开发的场景启动器。
5、所有场景启动器最底层的依赖
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter</artifactId>
  <version>2.3.4.RELEASE</version>
  <scope>compile</scope>
</dependency>

无序关注依赖版本号,自动进行版本仲裁

1、引入的依赖默认都是可以不写版本号

2、引入非版本仲裁的jar包,需要写入版本号

修改默认版本号

通过对springBoot项目的父项目的父项目,管理依赖版本号的方式我们可以发现,它是使用来管理依赖版本号,所以我们可以 使用Maven的依赖导入就近原则,在我们项目的pom.xml配置文件使用来切换修改默认版本号。

1、查看spring-boot-dependencies里面规定当前依赖的版本 用的 key。
2、在当前项目里面重写配置
3、如何写可以参考对应的父项目的父项目的写法
    <properties>
        <mysql.version>5.1.43</mysql.version>
    </properties>

6.3、SpringBoot自动配置

  • 自动配好SpringMVC

    • 引入SpringMVC全套组件
    • 自动配好SpringMVC常用组件(功能)
  • 自动配好Web常见功能,如:字符编码问题

    • SpringBoot帮我们配置好了所有web开发的常见场景
  • 默认的包结构

    • 主程序所在包及其下面的所有子包里面的组件都会被默认扫描进来
    • 无需以前的包扫描配置
    • 想要改变扫描路径,@SpringBootApplication(scanBasePackages=“com.atguigu”)
      • 或者@ComponentScan 指定扫描路径
@SpringBootApplication
等同于
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.atguigu.boot")
  • 各种配置拥有默认值

    • 默认配置最终都是映射到某个类上,如:MultipartProperties(我们上面简述的javaBean开启配置属性绑定)
    • 配置文件的值最终会绑定每个类上,这个类会在容器中创建对象(@enableConfigurationProperties)
  • 按需加载所有自动配置项(注解@Conditional 条件装配)

    • 非常多的starter
    • 引入了哪些场景这个场景的自动配置才会开启
    • SpringBoot所有的自动配置功能都在 spring-boot-autoconfigure 包里面

6.4、SpringBoot自动配置原理入门

6.4.1、@SpringBootApplication

找到我们的主启动类,进入@SpringBootApplication注解如下

被三个注解修饰

1、@SpringBootConfiguration

2、@ComponentScan

3、@EnableAutoConfiguration
springboot自动配置原理分析

6.4.1.1、@SpringBootConfiguration

进入此注解中发现它又被@configuration修饰,所以这个@SpringBootConfiguration注解只是一个表示当前是一个配置类,

说明主程序启动类也就是一个springBoot的配置类

springboot自动配置原理分析

6.4.1.2、@ComponentScan

指定扫描哪些包下组件,Spring注解

6.4.1.3、@EnableAutoConfiguration(重头戏)

先简单翻译一下,开启自动配置,进入此注解中可以发现被@AutoConfigurationPackage修饰,以及@Import(AutoConfigurationImportSelector.class)导入一个可以选择导入组件的组件
springboot自动配置原理分析

1、@AutoConfigurationPackage

进入@AutoConfigurationPackage中,如下
springboot自动配置原理分析
导入一个组件AutoConfigurationPackages.Registrar

利用Registrar给容器中导入一系列组件

将指定包下的组件导入进来(主启动类所在包)

1.1、AutoConfigurationPackages.Registrar

进入到这个组件中,有两个方法,进行批量的导入指定包下组件

/**
 * {@link ImportBeanDefinitionRegistrar} to store the base package from the importing
 * configuration.
 */
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));
   }

}

springboot自动配置原理分析

2、@Import(AutoConfigurationImportSelector.class)
1、利用getAutoConfigurationEntry(annotationMetadata);给容器中批量导入一些组件
2、调用List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes)获取到所有需要导入到容器中的配置类
3、利用工厂加载 Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader);得到所有的组件
4、从META-INF/spring.factories位置来加载一个文件。
	默认扫描我们当前系统里面所有META-INF/spring.factories位置的文件
    spring-boot-autoconfigure-2.3.4.RELEASE.jar包里面也有META-INF/spring.factories
    

进入到AutoConfigurationImportSelector类中,可以发现一个方法selectImports,调用getAutoConfigurationEntry(annotationMetadata);给容器中批量导入一些组件
springboot自动配置原理分析
进入getAutoConfigurationEntry方法中,又调用getCandidateConfigurations获取所有需要导入到容器中配置类
springboot自动配置原理分析
进入getCandidateConfigurations方法中,利用loadFactoryNames工厂加载得到所有组件
springboot自动配置原理分析
进入loadFactoryNames方法体中,发现有调用来了loadSpringFactories
springboot自动配置原理分析
进入loadSpringFactories中发现

加载一个META-INF/spring.factories目录下文件,得到所有组件
主要使用org.springframework.boot.autoconfigure下spring.factories

springboot自动配置原理分析

org.springframework.boot.autoconfigure/META-INF/spring.factories 所有自动配置类信息,我们最终就是加载这个配置文件中所有组件,但是启动时按需配置,开启

Auto Configure

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.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.ElasticsearchRestClientAutoConfiguration,
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,
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.JdbcTemplateAutoConfiguration,
org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,
org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,
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.jersey.JerseyAutoConfiguration,
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.embedded.EmbeddedMongoAutoConfiguration,
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.quartz.QuartzAutoConfiguration,
org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration,
org.springframework.boot.autoconfigure.r2dbc.R2dbcTransactionManagerAutoConfiguration,
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.solr.SolrAutoConfiguration,
org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration,
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.jta.JtaAutoConfiguration,
org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,
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.ReactiveWebServerFactoryAutoConfiguration,
org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration,
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

6.5、按需开启自动配置项

META-INF/spring.factories下的所有自动配置类组件在启动时,默认全部加载进来,但是会按需(按照条件装配规则@Conditional),进行配置
意思就是,启动时全部加载,但是会按照条件装配原则开启配置。

6.6、自动配置按需开启示例分析

aop:自动配置

一个缺少advice,不满足条件,配置失效,

一个满足添加,配置生效

springboot自动配置原理分析

web

dispatchservlet
springboot自动配置原理分析
springboot自动配置原理分析
开WebMvcProperties类绑定spring.mvc 前缀
springboot自动配置原理分析
配置文件上传

springboot自动配置原理分析

HttpEncodingAutoConfiguration 编码自动配置

springboot自动配置原理分析

6.7、总结

springBoot会默认在底层配置好所有的组件,如果用户没有配置,就是使用底层配置好的,要是用户配置了,就是使用用户配置

自动配置类,一般情况下回开启配置属性绑定,绑定配置文件指定的值,在xxxx.Properties里面拿。xxxProPerties和配置文件进行了绑定。

eg:

自动配置类,开始配置属性绑定
springboot自动配置原理分析

绑定配置文件前缀为server开头

springboot自动配置原理分析

配置文件书写
springboot自动配置原理分析

  • SpringBoot先加载所有的自动配置类 xxxxxAutoConfiguration

  • 每个自动配置类按照条件进行生效,默认都会绑定配置文件指定的值。xxxxProperties里面拿。xxxProperties和配置文件进行了绑定

  • 生效的配置类就会给容器中装配很多组件

  • 只要容器中有这些组件,相当于这些功能就有了

  • 定制化配置

    • 用户直接自己@Bean替换底层的组件
    • 用户去看这个组件是获取的配置文件什么值就去修改。

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

上一篇:【Spring Boot】源码解析(一):启动过程


下一篇:*学编程系列之SpringBoot自动配置原理