自动配置原理

自动配置原理

声明:本文章属于学习笔记,根据尚硅谷雷丰阳老师的SpringBoot编写
Spring官方文档

一丶依赖管理

首先我们要知道springboot这个东西有一个父依赖:

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
        <relativePath/>
    </parent>

我们点击进去:
在这里插入图片描述

我们在点击:
在这里插入图片描述

我们可以看到其实这里有各种依赖的版本号,几乎声明了所有开发中常用的依赖的版本号,自动版本仲裁机制

开发导入starter场景启动器:

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、查看spring-boot-dependencies里面规定当前依赖的版本 用的 key。
2、在当前项目里面重写配置
    <properties>
        <mysql.version>5.1.43</mysql.version>
    </properties>

二丶自动配置

自动配好Tomcat,在这里我们其实就已经在依赖注入的时候配置好了Tomcat,就是由于自动配置,所以才会有这个Tomcat的依赖
引入Tomcat依赖。
配置Tomcat:

<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
      <version>2.3.4.RELEASE</version>
      <scope>compile</scope>
    </dependency>

默认的包结构
主程序所在包及其下面的所有子包里面的组件都会被默认扫描进来
无需以前的包扫描配置
想要改变扫描路径,@SpringBootApplication(scanBasePackages=“com.atguigu”)
或者@ComponentScan 指定扫描路径

@SpringBootApplication
等同于
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.atguigu.boot")

各种配置拥有默认值
默认配置最终都是映射到某个类上,如:MultipartProperties
配置文件的值最终会绑定每个类上,这个类会在容器中创建对象
按需加载所有自动配置项
非常多的starter
引入了哪些场景这个场景的自动配置才会开启
SpringBoot所有的自动配置功能都在 spring-boot-autoconfigure 包里面

三丶容器功能

1丶组件添加

我们首先看这两个类:

package com.kdy.boot.bean;

/**
 * @author kdy
 * @create 2021-07-14 21:17
 */
public class Pet {

    private  String name;

    public Pet(String name) {
        this.name = name;
    }

    public Pet() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Pet{" +
                "name='" + name + '\'' +
                '}';
    }
}

package com.kdy.boot.bean;

/**
 * @author kdy
 * @create 2021-07-14 21:16
 */
public class User {

    private String name;
    private int age;

    public User() {
    }

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

我们在学习spring的时候进行组件的添加到容器中,是要编写bean.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="user" class="com.kdy.boot.bean.User">
        <property name="name" value="kdy"></property>
        <property name="age" value="21"> </property>
    </bean>

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

这样我们才算把组件添加到spring容器中。
当我们学习springboot的时候我们可以用另一种方法进行添加。

package com.kdy.boot.config;

import com.kdy.boot.bean.Pet;
import com.kdy.boot.bean.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author kdy
 * @create 2021-07-14 21:30
 */

@Configuration//告诉SpringBoot这是一个配置类 == 配置文件(代替了bean.xml配置文件)
public class MyConfig {

    @Bean//给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例

    public User user01(){
        return new User("kdy",21);
    }

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

之后我们编写主类的代码程序:

package com.kdy.boot;

import com.kdy.boot.bean.Pet;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

/**
 * @author kdy
 * @create 2021-07-13 20:04
 */
@SpringBootApplication
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 kdy1 = run.getBean("tomcat", Pet.class);
        Pet kdy2 = run.getBean("tomcat", Pet.class);

        System.out.println(kdy1==kdy2);
    }
}

在这里插入图片描述

在这里插入图片描述

我们可以看见我们添加成功的。

2丶@Configuration

@Configuration告诉SpringBoot这是一个配置类 == 配置文件。

@Configuration(proxyBeanMethods = true)就是声明将此类变为代理类。

在这里插入图片描述

在这里插入图片描述我们可以看见当我们这么写的时候这个类就变成了代理类对象EnhancerBySpringCGLIB

@Configuration(proxyBeanMethods = false)的时候,就声明不将其变为代理类。

所有我们应该什么时候true,什么时候用false呢?
首先我们要知道:
proxyBeanMethods:代理bean的方法

Full(proxyBeanMethods = true)【保证每个@Bean方法被调用多少次返回的组件都是单实例的】
Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的】
组件依赖必须使用Full模式默认。其他默认是否Lite模式

也就是说当我们的需要组件依赖的时候我们才要用到Full模式,当我们不用到组件依赖的时候我们用Lite模式,因为Lite模式下要比Full模式下正常启动快速。

那么什么是组件依赖呢?组件依赖也就是说我们要依赖某个组件才可以实现谋个组件的业务逻辑。所以我们一定要保持这个类的对象唯一

public class MyConfig {

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

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

}

我们看这样一段代码,这个user01是依赖于tom组件的,Full模式。

    User user = bean.user01();
        User user1 = bean.user01();
        System.out.println("是否为单实例:"+(user == user1));


        User user01 = run.getBean("user01", User.class);
        Pet pet = run.getBean("tom", Pet.class);
        System.out.println("用户的宠物"+(user01.getPet()==pet));

运行结果:
在这里插入图片描述
我们再看Lite模式:
在这里插入图片描述

所以我们可以得出:

如果@Configuration(proxyBeanMethods = true)代理对象调用方法。SpringBoot总会检查这个组件是否在容器中有。如果有则保持组件单实例。

因为只有将其称为代理类,将其保持单例模式,我们才可以放心的让谋个组件完全依赖于谋个组件。

3丶@Import

@Import({User.class, DBHelper.class})
   给容器中自动创建出这两个类型的组件、默认组件的名字就是全类名

@Import({User.class, DBHelper.class})
@Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件
public class MyConfig {
}
      String[] namesForType = run.getBeanNamesForType(User.class);
        System.out.println("==============");
        for (String s : namesForType) {
            System.out.println(s);
        }

        DBHelper bean1 = run.getBean(DBHelper.class);
        System.out.println(bean1);

在这里插入图片描述

4丶 @Conditional

首先我们要知道知道这个注解是什么意思?
条件装配:满足Conditional指定的条件,则进行组件注入。这个注解也简称是条件注解。
我们看张图片:
在这里插入图片描述我们不将其当做组件注入到容器中:

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

运行结果:
在这里插入图片描述

这个时候我们是没有tom组件的。

我们在看这样的一段代码:

@Configuration(proxyBeanMethods = true)//告诉SpringBoot这是一个配置类 == 配置文件(代替了bean.xml配置文件)

public class MyConfig {

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

    //@ConditionalOnBean(name="tom")
    @Bean//给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
    public User user01(){
        User kdy = new User("kdy", 21);
        kdy.setPet(tomcat());
        return kdy;
    }

}

我们都知道user01这个组件是依赖于tom这个组件的入股我们将其注释掉,如果没有这样,容器中依然也有这个组件,但是器功能也就丧失了:
在这里插入图片描述

在这时我们将上面的注释注解去掉:
在这里插入图片描述
运行结果:

在这里插入图片描述

我们可以看见user01没有注入容器中。
我们刚刚是放在了方法上如果放在类上呢?

在这里插入图片描述
在这里插入图片描述

我们可以看见也都没有注入进来。所以这个注解到底是什么意思呢?
其实就是:

放在配置类上表示,当容器中满足条件时,配置类中的组件才生效;
放在配置方法上的时候,表示的意思是当满足条件的时候配置方法才生效;

与他相对的是@ConditionalOnMissingBean,他的意思是“没有满足条件时”:
在这里插入图片描述

在这里插入图片描述

我们可以看见当我们没有这个组件时将组件注入到了容器中。

5丶配置绑定

以前我们进行配置绑定的时候我们要将配置文件bean封装到javabean中。供我们经常使用,但是现在我们用注解也可以完全实现。

@Component+@ConfigurationProperties

我们看这样的一段代码,

package com.kdy.boot.bean;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * @author kdy
 * @create 2021-07-19 15:00
 */
@Component
@ConfigurationProperties(prefix ="mycar")
public class Car {

    private String brand;
    private Integer price;

    public Car(String brand, Integer price) {
        this.brand = brand;
        this.price = price;
    }

    public Car() {
    }

    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 +
                '}';
    }
}

在这里插入图片描述

我们可以看到这是我们创建的Car类,我们要将其进行属性绑定。
在这里插入图片描述
@Component这个注解就是将前缀为类mycar注入容器中,如果我们没有这个注解就会报错:
在这里插入图片描述也就是说他找不到这个bean,与其说找不到,其实就是根本没有。

因为只有我们将他注入进来,他才可以使用springboot的强大功能。

我们进行测试:

    @RestController
public class HelloController {
        @Autowired
        Car car;
        @RequestMapping("/car")
        public Car car(){
            return car;
        }
      }

在这里我要说一下@Autowired,这个注解起到自动装配的作用,我们将这个Car注入进来,我们将进行Car自动装配,将他也注入进来。我们才可以是使用 Car car。

如果没有@Autowired;
在这里插入图片描述
有@Autowired:
在这里插入图片描述
我们可以看到运行成功。

这只是第一种配置绑定的方法。还有第二种:

@EnableConfigurationProperties + @ConfigurationProperties

@EnableConfigurationProperties这个注解一定要写在配置类上!

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

说明一下为什么需要第二种方法。如果@ConfigurationProperties是在第三方包中,那么@component是不能注入到容器的。只有@EnableConfigurationProperties才可以注入到容器。

四丶自动配置原理入门

1丶自动导包底层代码原理规则

说起自动扫描包我们一定会想起@SpringBootApplication这个注解。这个注解只要在springboot的主类就代表这是一个springboot程序。他还有自动扫描包的功能。

@SpringBootApplication=@SpringBootConfiguration+@ComponentScan+@EnableAutoConfiguration

当然@SpringBootApplication这个注解的源码还有很多注解:
在这里插入图片描述

但主要的功能其实就是这三个注解的拆分。

源码:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

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丶@SpringBootConfiguration

标注这个类是一个配置类;它只是@Configuration注解的派生注解;
它与@Configuration注解的功能一致,唯一的区别是@SpringBootConfiguration可以自动找到配置,而@SpringBootConfiguration是springboot的注解,而@Configuration是spring的注解。

2丶@ComponentScan:

扫描包的功能

3丶@EnableAutoConfiguration:

在这里插入图片描述这个注解主要也包括两个重要的注解一个是@AutoConfigurationPackage另一个是
@Import({AutoConfigurationImportSelector.class})

@AutoConfigurationPackage:
自动配置包,指定了自动配置包规则:

在这里插入图片描述
我们看源码可以看见@import其实就也是给Springboot容器添加组件。
也就是添加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));
		}

	}

在这里插入图片描述

我们看这个调用redister其实最后返回的是个数组。所以这个就是说Registrar类作为组件导入到容器中,然后使用Registrar中的方法批量完成组件的注册。

@Import({AutoConfigurationImportSelector.class}):

1、利用getAutoConfigurationEntry(annotationMetadata);给容器中批量导入一些组件
2、调用List configurations = getCandidateConfigurations(annotationMetadata, attributes)获取到所有需要导入到容器中的配置类
3、利用工厂加载 Map<String, List> 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

在这里插入图片描述

文件里面写死了spring-boot一启动就要给容器中加载的所有配置类
spring-boot-autoconfigure-2.3.4.RELEASE.jar/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.Neo4jRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcTransactionManagerAutoConfiguration,\
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.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,\
org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration,\
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.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

虽然我们127个场景的所有自动配置启动的时候默认全部加载。xxxxAutoConfiguration
按照条件装配规则(@Conditional),最终会按需配置。

在这里插入图片描述

就像上面的这个类:
在这里插入图片描述
如果没有这个类那么这个条件注解就无法执行,也就是无法添加组件。

2丶修改默认配置

        @Bean
		@ConditionalOnBean(MultipartResolver.class)  //容器中有这个类型组件
		@ConditionalOnMissingBean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME) //容器中没有这个名字 multipartResolver 的组件
		public MultipartResolver multipartResolver(MultipartResolver resolver) {
            //给@Bean标注的方法传入了对象参数,这个参数的值就会从容器中找。
            //SpringMVC multipartResolver。防止有些用户配置的文件上传解析器不符合规范
			// Detect if the user has created a MultipartResolver but named it incorrectly
			return resolver;
		}
给容器中加入了文件上传解析器;

在这里插入图片描述

也就是说multipartResolver,容器中哟这个类但是没有这个名字的时候才可以执行下面的程序。这个东西很有意思,我们不需要进行传值,只要传参之后就会自定去容器中找。

SpringBoot默认会在底层配好所有的组件。但是如果用户自己配置了以用户的优先。
也就是我们常说的约定大于配置。

总结:

SpringBoot先加载所有的自动配置类 xxxxxAutoConfiguration
每个自动配置类按照条件进行生效,默认都会绑定配置文件指定的值。xxxxProperties里面拿。xxxProperties和配置文件进行了绑定
生效的配置类就会给容器中装配很多组件
只要容器中有这些组件,相当于这些功能就有了
定制化配置
用户直接自己@Bean替换底层的组件
用户去看这个组件是获取的配置文件什么值就去修改。
xxxxxAutoConfiguration —> 组件 —> xxxxProperties里面拿值 ----> application.properties
(底层很重要,我们正确的修改application.properties的配置有两个方法:1丶查看官方文档 2丶读懂底层源码)

其实说了这个多的原理究竟实践怎么实践呢?
我们看这样的配置:
在这里插入图片描述之后启动项目:

在这里插入图片描述
在这里插入图片描述

positive是条件注解直接成功之后的的,就是添加到容器中红的组件,
negative是条件注没有成功之后的的,就是没有添加到容器中红的组件,
两个都会说明原因。

其实我在这里也就是想说明:我们可以通过application.properties来进行配置的更新。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值