SpringBoot(02) -- 自动配置原理

SpringBoot2学习笔记

源码地址

一、SpringBoot2基础入门

二、自动配置原理

2.1)SpringBoot特点

2.1.1)依赖管理

父项目做依赖管理

<!--依赖管理-->  
<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
</parent>
​
<!--它的父项目-->  
 <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>2.3.4.RELEASE</version>
  </parent>
  
<!--其中几乎声明了所有开发中常用的依赖的版本号,自动版本仲裁机制-->  

可以修改默认版本号

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

开发导入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. 无需关注版本号,自动版本仲裁

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

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

2.1.2)自动配置

自动配好Tomcat --> 引入Tomcat依赖,配置Tomcat

 <!--
 1、查看spring-boot-dependencies里面规定当前依赖的版本 用的 key。
 2、在当前项目里面重写配置
 -->
     <properties>
         <mysql.version>5.1.43</mysql.version>
     </properties>
  1. 自动配好SpringMVC

引入SpringMVC全套组件并自动配好SpringMVC常用组件(功能)

  1. 自动配好Web常见功能,如:字符编码问题

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

  1. 默认的包结构

  • 主程序所在包及其下面的所有子包里面的组件都会被默认扫描进来,无需以前的包扫描配置;

  • 想要改变扫描路径,@SpringBootApplication(scanBasePackages="com.study") 或者@ComponentScan 指定扫描路径,如下:

//主程序所在包及其下面的所有子包里面的组件都会被默认扫描进来
@SpringBootApplication
// 修改扫描路径方案一:
//@SpringBootApplication(scanBasePackages="com.study")
// 修改扫描路径方案二:添加下列三个注解代替@SpringBootApplication
//@SpringBootConfiguration
//@EnableAutoConfiguration
//@ComponentScan("com.study")
  1. 各种配置拥有默认值

  • 默认配置最终都是映射到某个类上,如:MultipartProperties

  • 配置文件的值最终会绑定每个类上,这个类会在容器中创建对象

  1. 按需加载所有自动配置项

  • 非常多的starter

  • 引入了哪些场景这个场景的自动配置才会开启

  • SpringBoot所有的自动配置功能都在 spring-boot-autoconfigure 包里面,如下图:

2.2)容器功能

2.2.1)组件添加

修改SpringBootDemo1工程中的POM.xml文件,添加lombok,代码如下:

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

新建实体类 Pet.java,代码如下:

@ToString
@Data
@NoArgsConstructor  //无参构造器
@AllArgsConstructor  //全参构造器
public class Pet {
    private String name;
}

新建实体类 User.java,代码如下:

@NoArgsConstructor
@Data
@ToString
@EqualsAndHashCode
public class User {
    private String name;
    private Integer age;
    private Pet pet;
​
    public User(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
}

2.2.1.1)@Configuration

新建配置类 MyConfig.java,代码如下:

@Configuration
public class MyConfig {
    //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
    @Bean
    public User user01() {
        User zhangsan = new User("zhangsan", 18);
        return zhangsan;
    }
​
    @Bean("tom")
    public Pet tomcatPet() {
        return new Pet("tomcat");
    }
}

上述代码中:

  • 配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实例的

  • 配置类本身也是组件

修改主程序启动类MainApplication.java,代码如下:

@SpringBootApplication
public class MainApplication {
    public static void main(String[] args) {
        // 默认启动
        // SpringApplication.run(MainApplication.class, 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));
        MyConfig bean = run.getBean(MyConfig.class);
    }
}
控制台输出:
查看容器里面的组件 = 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
查看容器里面的组件 = mainApplication
...
查看容器里面的组件 = spring.servlet.multipart-org.springframework.boot.autoconfigure.web.servlet.MultipartProperties
查看容器里面的组件 = org.springframework.aop.config.internalAutoProxyCreator

Full模式与Lite模式

Lite模式:【默认情况】【proxyBeanMethods = true】配置类组件之间无依赖关系,加速容器启动过程,减少判断;保证每个@Bean方法被调用多少次返回的组件都是单实例的,已存在的不会重新创建;

Full模式:【proxyBeanMethods = false】配置类组件之间有依赖关系,方法会被调用得到之前单实例组件;每个@Bean方法被调用多少次返回的组件都是新创建的

修改主程序启动类MainApplication.java,代码如下:

  //3、从容器中获取组件
        Pet tom01 = run.getBean("tom", Pet.class);
        Pet tom02 = run.getBean("tom", Pet.class);
        System.out.println("容器中获取组件相同:"+(tom01 == tom02));
        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));

修改配置类 MyConfig.java,代码如下:

@Configuration(proxyBeanMethods = true)

控制台输出:

容器中获取组件相同:true
从容器中获取组件 = com.study.boot.config.MyConfig$$EnhancerBySpringCGLIB$$c86081cf@323f3c96
组件单实例 = true
用户的宠物:false

修改配置类 MyConfig.java,代码如下:

@Configuration(proxyBeanMethods = false)

控制台输出:

容器中获取组件相同:true
从容器中获取组件 = com.study.boot.config.MyConfig@761e788f
组件单实例 = false
用户的宠物:false

2.2.1.2)@Import

导入外部组件,给容器中自动创建出这两个类型的组件、默认组件的名字就是全类名

修改配置类 MyConfig.java,代码如下:

@Import({User.class, DBHelper.class})
public class MyConfig {
...
}

修改主程序启动类MainApplication.java,代码如下:

        //5、获取组件
        String[] beanNamesForType = run.getBeanNamesForType(User.class);
        for (String s : beanNamesForType) {
            System.out.println("获取组件1 = " + s);
        }
        System.out.println("=========================");
        DBHelper bean1 = run.getBean(DBHelper.class);
        System.out.println("获取组件2 = " + bean1);

控制台输出:【默认组件的名字就是全类名】

获取组件1 = com.study.boot.bean.User
获取组件1 = user01
=========================
获取组件2 = ch.qos.logback.classic.db.DBHelper@73fb1d7f

2.2.1.2)@Conditional

@ConditionalOnBean:条件装配,满足Conditional指定的条件,则进行组件注入

修改配置类 MyConfig.java,代码如下:

@Configuration
// 条件装配:满足Conditional指定的条件,则进行组件注入,即容器中存在名称为tom的组件则将该类中包含的组件(user01和tom2)进行注入
@ConditionalOnBean(name = "tom")
public class MyConfig {
    //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
    @Bean
    public User user01() {
        User zhangsan = new User("zhangsan", 18);
        return zhangsan;
    }
​
    @Bean("tom")
    public Pet tomcatPet() {
        return new Pet("tomcat");
    }
​
    @Bean("tom2")
    public Pet tomcatPet2() {
        return new Pet("tomcat2");
    }
}

修改主程序启动类MainApplication.java,代码如下:

   //6、 条件装配:满足Conditional指定的条件,则进行组件注入
        boolean tom = run.containsBean("tom");
        System.out.println("容器中Tom组件:" + tom);
​
        boolean user01 = run.containsBean("user01");
        System.out.println("容器中user01组件:" + user01);
​
        boolean tom22 = run.containsBean("tom2");
        System.out.println("容器中tom2组件:" + tom2);

控制台输出:【容器中存在名称为tom的组件则将该类中包含的组件(user01和tom2)进行注入】

容器中Tom组件:false
容器中user01组件:false
容器中tom2组件:false

@ConditionalOnMissingBean:条件装配,不满足Conditional指定的条件,则进行组件注入

修改配置类 MyConfig.java,代码如下:

// 条件装配:不满足Conditional指定的条件,则进行组件注入,即容器中不存在名称为tom的组件则将该类中包含的组件(user01和tom2)进行注入
@ConditionalOnMissingBean(name = "tom")
public class MyConfig {
...
}

控制台输出:【容器中不存在名称为tom的组件则将该类中包含的组件(user01和tom2)进行注入】

容器中Tom组件:true
容器中user01组件:true
容器中tom22组件:true

2.2.2)原生配置文件引入

2.2.2.1)@ImportResource

导入外部bean的配置文件,支持以原生Spring解析xml文件的方式将bean对象注入到容器中

修改主程序启动类MainApplication.java,代码如下:

        //7、导入外部bean的配置文件:判断容器中是否存在该bean的对象
        boolean haha = run.containsBean("haha");
        boolean hehe = run.containsBean("hehe");
        System.out.println("haha:"+haha);
        System.out.println("hehe:"+hehe);

控制台输出:【未导入配置文件,容器中不存在名称为haha的和hehe的组件则】

haha:false
hehe:false

修改配置类 MyConfig.java,代码如下:

//导入外部bean的配置文件,解析该文件后将相关内容进行组件注入到容器中
@ImportResource("classpath:beans.xml")
public class MyConfig {
    //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
    @Bean
    public User user01() {
        User zhangsan = new User("zhangsan", 18);
        return zhangsan;
    }
​
    @Bean("tom")
    public Pet tomcatPet() {
        return new Pet("tomcat");
    }
​
    @Bean("tom2")
    public Pet tomcatPet2() {
        return new Pet("tomcat2");
    }
}

新增bean配置文件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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
​
    <bean id="haha" class="com.study.boot.bean.User">
        <property name="name" value="zhangsan"></property>
        <property name="age" value="18"></property>
    </bean>
​
    <bean id="hehe" class="com.study.boot.bean.Pet">
        <property name="name" value="tomcat"></property>
    </bean>
</beans>

控制台输出:【导入配置文件后,容器中存在名称为haha的和hehe的组件则】

haha:true
hehe:true

2.2.3)配置绑定

将全局使用到的且需要修改的东西写到properties文件中,使用Java读取到properties文件中的内容,并且把它封装到JavaBean中,以供随时使用,原生实现方式代码如下:

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。
         }
     }
 }

使用SpringBoot相关注解,方式如下:

2.2.3.1)@Component + @ConfigurationProperties

新增bean对象 Car.java,方式如下:

@ToString
@Data
// 添加到容器中,只有在容器中的组件,才会拥有SpringBoot提供的强大功能
@Component
// 配置绑定,prefix:和application.properties配置文件中的前缀【mycar开头】的内容进行绑定
@ConfigurationProperties(prefix = "mycar")
public class Car {
    private String brand;
    private Integer price;
}

修改配置文件application.properties,方式如下:

#配置绑定测试
mycar.brand=BYD
mycar.price=100000

修改HelloController.java,方式如下:

@RestController
public class HelloController {
    @RequestMapping("/hello")
    public String handle01() {
        return "Hello, Spring Boot 2!";
    }
    // 配置绑定测试
    @Autowired
    Car car;
​
    @RequestMapping("/car")
    public Car car(){
        return car;
    }
}

测试:浏览器访问 http://localhost:8888/car,页面如下,将配置文件中的内容解析并与bean对象进行绑定

 2.2.3.2)@EnableConfigurationProperties + @ConfigurationProperties

修改bean对象 Car.java,方式如下:

@ToString
@Data
// 配置绑定,prefix:和application.properties配置文件中的前缀【mycar开头】的内容进行绑定
@ConfigurationProperties(prefix = "mycar")
public class Car {
    private String brand;
    private Integer price;
}

修改配置类 MyConfig.java,代码如下:

@Configuration
@EnableConfigurationProperties(Car.class)
//1、开启属性配置功能,给Car配置绑定功能
//2、把这个Car这个组件自动注册到容器中
public class MyConfig {
    //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
    @Bean
    public User user01() {
        User zhangsan = new User("zhangsan", 18);
        return zhangsan;
    }
}

测试:浏览器访问 http://localhost:8888/car,页面如下,将配置文件中的内容解析并与bean对象进行绑定

2.3)自动配置原理概述

2.3.1)引导加载自动配置类

主程序启动类MainApplication.java,代码如下:

//主程序类,这是一个SpringBoot应用,主程序所在包及其下面的所有子包里面的组件都会被默认扫描进来
@SpringBootApplication
// 修改扫描路径方案一:
//@SpringBootApplication(scanBasePackages="com.study")
// 修改扫描路径方案二:添加下列三个注解代替@SpringBootApplication
//@SpringBootConfiguration
//@EnableAutoConfiguration
//@ComponentScan("com.study")
public class MainApplication {
    public static void main(String[] args) {
        // 默认启动
         SpringApplication.run(MainApplication.class, args);
      }
}

说明 @SpringBootApplication 注解,相当于

@SpringBootConfiguration

@EnableAutoConfiguration

@ComponentScan

2.3.2)@SpringBootConfiguration

注解类SpringBootConfiguration.java,代码如下:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
    @AliasFor(
        annotation = Configuration.class
    )
    boolean proxyBeanMethods() default true;
}

@Configuration:代表当前是一个配置类

2.3.3)@ComponentScan

@ComponentScan:指定扫描哪些路径下的相关内容

2.3.4)@EnableAutoConfiguration

注解类EnableAutoConfiguration.java,代码如下:

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

2.3.4.1)@AutoConfigurationPackage

注解类AutoConfigurationPackage.java,代码如下:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({Registrar.class})
public @interface AutoConfigurationPackage {
    String[] basePackages() default {};
​
    Class<?>[] basePackageClasses() default {};
}

@Import:给容器中导入一个组件 Registrar,Registrar源码如下:【利用Registrar给容器中导入一系列组件,

将指定的一个包下(MainApplication 所在包下)的所有组件导入进来】

public abstract class AutoConfigurationPackages {
    ...
    static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
        Registrar() {
        }
​
        public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
            AutoConfigurationPackages.register(registry, (String[])(new AutoConfigurationPackages.PackageImports(metadata)).getPackageNames().toArray(new String[0]));
        }
​
        public Set<Object> determineImports(AnnotationMetadata metadata) {
            return Collections.singleton(new AutoConfigurationPackages.PackageImports(metadata));
        }
    }
}

2.3.4.2)@Import({AutoConfigurationImportSelector.class})

AutoConfigurationImportSelector.java源码如下:

public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
​
...
​}
  1. 利用getAutoConfigurationEntry(annotationMetadata),给容器中批量导入一些组件;

AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
  1. 调用List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes)获取到所有需要导入到容器中的配置类;

  1. 利用工厂加载 Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader),得到所有的配置类

    protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
        List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
        Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
        return configurations;
    }

loadFactoryNames方法源码如下:

 public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
        String factoryTypeName = factoryType.getName();
        return (List)loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
    }

loadSpringFactories 源码如下:

private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
        MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
      ...
 }
  1. 从META-INF/spring.factories位置来加载一个文件,默认扫描当前系统里面所有META-INF/spring.factories位置的文件

loadSpringFactories 源码如下:

private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
        MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
        if (result != null) {
            return result;
        } else {
            try {
                Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
                LinkedMultiValueMap result = new LinkedMultiValueMap();
       ...
 }              

spring-boot-autoconfigure-2.3.4.RELEASE.jar包里面也有META-INF/spring.factories【包含127个配置场景】

 2.3.2)按需开启自动配置项

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

2.3.3)修改默认配置

给容器中加入了文件上传解析器,源码如下:

        @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;
        }

SpringBoot默认会在底层配好所有的组件,但是如果用户自己配置了以用户的优先

public class HttpEncodingAutoConfiguration {
    private final Encoding properties;
​
    public HttpEncodingAutoConfiguration(ServerProperties properties) {
        this.properties = properties.getServlet().getEncoding();
    }
​
    @Bean
    @ConditionalOnMissingBean
    public CharacterEncodingFilter characterEncodingFilter() {
        CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
        filter.setEncoding(this.properties.getCharset().name());
        filter.setForceRequestEncoding(this.properties.shouldForce(org.springframework.boot.web.servlet.server.Encoding.Type.REQUEST));
        filter.setForceResponseEncoding(this.properties.shouldForce(org.springframework.boot.web.servlet.server.Encoding.Type.RESPONSE));
        return filter;
    }
    ...
}

用户自定义characterEncodingFilter(),修改配置类 MyConfig.java,代码如下:

@Configuration
public class MyConfig {
    // 用户自定义characterEncodingFilter()
    @Bean
    public CharacterEncodingFilter filter(){
        return null;
    }
}

SpringBoot自动配置流程如下:

  1. SpringBoot先加载所有的自动配置类 xxxxxAutoConfiguration;

  2. 每个自动配置类按照条件进行生效,默认都会绑定配置文件指定的值,从xxxxProperties里面获取配置信息,xxxProperties和配置文件进行了绑定

  3. 生效的配置类就会给容器中装配很多组件,只要容器中有这些组件,相当于这些功能就有了

  4. 定制化配置

    • 用户直接自己@Bean替换底层的组件

    • 用户去看这个组件是获取的配置文件什么值就去修改

xxxxxAutoConfiguration ---> 导入组件 ---> xxxxProperties里面获取配置信息 ----> 从application.properties获取配置信息

例如:缓存自动配置类 CacheAutoConfiguration.java,源码如下:

@Configuration(
    proxyBeanMethods = false
)
@ConditionalOnClass({CacheManager.class})
@ConditionalOnBean({CacheAspectSupport.class})
@ConditionalOnMissingBean(
    value = {CacheManager.class},
    name = {"cacheResolver"}
)
@EnableConfigurationProperties({CacheProperties.class})
@AutoConfigureAfter({CouchbaseDataAutoConfiguration.class, HazelcastAutoConfiguration.class, HibernateJpaAutoConfiguration.class, RedisAutoConfiguration.class})
@Import({CacheAutoConfiguration.CacheConfigurationImportSelector.class, CacheAutoConfiguration.CacheManagerEntityManagerFactoryDependsOnPostProcessor.class})
public class CacheAutoConfiguration {
    public CacheAutoConfiguration() {
    }
    ...
}

可知配置信息与配置文件CacheProperties.class绑定,CacheProperties.java,源码如下:

@ConfigurationProperties(
    prefix = "spring.cache"
)
public class CacheProperties {
    private CacheType type;
    private List<String> cacheNames = new ArrayList();
    private final CacheProperties.Caffeine caffeine = new CacheProperties.Caffeine();
    private final CacheProperties.Couchbase couchbase = new CacheProperties.Couchbase();
    private final CacheProperties.EhCache ehcache = new CacheProperties.EhCache();
    private final CacheProperties.Infinispan infinispan = new CacheProperties.Infinispan();
    private final CacheProperties.JCache jcache = new CacheProperties.JCache();
    private final CacheProperties.Redis redis = new CacheProperties.Redis();
 ...
}

可知该配置文件的配置前缀是spring.cache,在工程的配置文件application.properties中可以自定义配置相关信息,如下图所示:

猜你喜欢

转载自blog.csdn.net/jianghao233/article/details/125096200