SpringBoot 配置文件与自动装配原理

本文详细介绍了SpringBoot的配置文件类型、位置、名字及内容,并探讨了配置文件注入属性的方法。此外,还深入解析了SpringBoot自动装配的原理,涉及到@EnableAutoConfiguration注解、配置类的条件加载以及META-INF/spring.factories文件的角色。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.关于 SpringBootSpringBootSpringBoot 的配置文件

1.0 配置文件的类型

SpringBootSpringBootSpringBoot 支持以下两类配置文件。

  1. 后缀为 .properties.properties.properties 的文件

  2. 后缀为 .yml.yml.yml 的文件

1.1 配置文件的位置

在创建一个 SpringBootSpringBootSpringBoot 工程时,默认在 resourcesresourcesresources 目录下有一个 application.propertiesapplication.propertiesapplication.properties 文件,这个文件就是 SpringBootSpringBootSpringBoot 自带的配置文件。但配置文件的位置并不是固定的。按照官方文档的介绍,配置文件可以放在以下四个位置,且优先级依次降低。

  • 项目的根目录下的 configconfigconfig 文件夹中(这个文件夹默认不存在,需要的话要自己创建)
  • 项目的根目录下
  • resourcesresourcesresources 目录下的 configconfigconfig 文件夹中(这个文件夹默认不存在,需要的话要自己创建)
  • resourcesresourcesresources 目录下(resources下就是classpath下resources下就是classpath下resourcesclasspath

SpringBootSpringBootSpringBoot 会依次加载这四个位置的配置文件,优先级高的配置会覆盖优先级低的配置,并形成互补配置。

当然,配置文件的位置也可以自己指定,但若不做相应的调整 ,SpringBootSpringBootSpringBoot 并不会去加载自定义的配置。我们可以在

在这里插入图片描述

设置spring.config.location=classpath:/路径/,这样项目启动时就加载的是自定义路径下的配置文件了。

若是jar包,我们可以通过下方命令修改路径。

java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar --spring.config.location=路径

1.2 配置文件的名字

SpringBootSpringBootSpringBoot 默认加载的配置文件的名字都为 application.xxx,但也可以是 application-{profile}.xxx 以应对多环境下不同的配置。但如有特殊需要,一定要修改application这个名字,并且保证 SpringBootSpringBootSpringBoot 默认加载自定义的配置文件,我们可以参照修改配置文件路径的方式,只不过这次是 spring.config.name=名字

对于不同环境下的配置,若要激活对应的配置文件,需要在默认的配置文件 application.xxx 中加 spring.profiles.active=xxx 来激活。

1.3 配置文件的内容
  1. 字面量,如基本数据类型
  2. 对象
  3. 数组
  4. List,Set,Map等
  5. 占位符,如随机数 $${random.*}$
1.4 利用配置文件注入属性
  1. 基于 @Value@Value@Value 注解,给已经在容器中JavaBeanJavaBeanJavaBean 注入属性
@Component
public class Dog{
    @Value("${dog.name}")
    private String name;
    //省略get/set方法
}

配置文件application.properties中
dog.name=BigDog
  1. 使用 @ConfigurationProperties@ConfigurationProperties@ConfigurationProperties 注解,给已经在容器中JavaBeanJavaBeanJavaBean 注入属性
@Component
@ConfigurationProperties(prefix = "dog")
public class Dog {
    private String name;
    //省略get/set方法
}

配置文件application.properties中
dog.name=BigDog

若我们需要给一个 BeanBeanBean 注入一个自定义的配置文件的属性,可以在 BeanBeanBean 上加 @PropertySource("classpath:配置文件")@PropertySource("classpath:配置文件")@PropertySource("classpath:") 注解,表明这个 BeanBeanBean 会加载我们指定的配置文件。

@PropertySource(value = {"classpath:dog.properties"})
@Component
@ConfigurationProperties(prefix = "dog")
public class Dog {
    private String name;
    //省略get/set方法
}

配置文件application.properties中
dog.name=BigDog

比较两种注入属性的方法

@ConfigurationProperties@Value
功能批量注入配置文件中的属性一个个指定
松散绑定(松散语法)支持不支持
SpEL不支持支持
JSR303数据校验支持不支持
复杂类型封装支持不支持

2.SpringBootSpringBootSpringBoot 自动装配原理

SpringBootSpringBootSpringBoot 自动装配的关键都在 @EnableAutoConfiguration@EnableAutoConfiguration@EnableAutoConfiguration 注解中。

进入 @EnableAutoConfiguration@EnableAutoConfiguration@EnableAutoConfiguration 中,可以看见它上面的注解

在这里插入图片描述

重点关注 @Import@Import@Import 注解。

这个注解是 SpringSpringSpring 中的注解,可以用来给容器中注入一个 BeanBeanBean ,而这里就是要给容器中注入一个AutoConfigurationImportSelectorAutoConfigurationImportSelectorAutoConfigurationImportSelector 类,这个类实现了 DeferredImportSelectorDeferredImportSelectorDeferredImportSelector 接口,这个接口继承了 ImportSelectorImportSelectorImportSelector 接口。

所以这个类必须重写String[] selectImports(AnnotationMetadata importingClassMetadata);方法,而这个方法的功能,返回一个包含要注入到容器中的Bean的名称的数组,元数据由配置类提供(@Configuration@Configuration@Configuration)。

/**
	 * Select and return the names of which class(es) should be imported based on
	 * the {@link AnnotationMetadata} of the importing @{@link Configuration} class.
	 * @return the class names, or an empty array if none
	 */
	String[] selectImports(AnnotationMetadata importingClassMetadata);

这个方法底层扫描了所有META-INF/spring.factories配置文件中的内容,所有需要创建的 BeanBeanBean 都在这里面,读取每个 starterstarterstarter 中的spring.factoriesspring.factoriesspring.factories 文件,封装成 propertiespropertiesproperties 对象,通过迭代器遍历取值,添加到容器中。

在这里插入图片描述

随便打开一个META-INF/spring.factories内容,都是一个个自动配置类 xxxAutoConfigurationxxxAutoConfigurationxxxAutoConfiguration

在这里插入图片描述

AopAutoConfigurationAopAutoConfigurationAopAutoConfiguration类为例

可以看见 @Configuration@Configuration@Configuration 注解,说明就是一个配置类,而这些配置类会提供元数据AnnotationMetadata importingClassMetadata,也能看见 @ConditionalOnXXX@ConditionalOnXXX@ConditionalOnXXX注解,说明要满足某些条件,这个BeanBeanBean才能被加入容器中。

总结:借由@EnableAutoConfiguration@EnableAutoConfiguration@EnableAutoConfiguration 注解,找到META−INF/spring.factoriesMETA-INF/spring.factoriesMETAINF/spring.factories文件,读取文件中的内容,而该文件里面都是一个个要被注入容器中的BeanBeanBean,满足条件后就被加入容器中,完成装配。

更多Java内容欢迎扫码关注我的公众号ACJavaBear,文章第一时间会发在上面。一起学Java吧
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值