面试题:SpringBoot 自动装配原理

面试题:SpringBoot 自动装配原理1 SpringBootAp 注解首先 我们都知道 SpringBoot 程序的入口是通过 SpringBootAp 注解修饰的一个类 例如 SpringBootAp publicstatic String args SpringApplic run ConfigApplic class args

1. @SpringBootApplication注解

首先,我们都知道SpringBoot程序的入口是通过@SpringBootApplication注解修饰的一个类,例如:

@SpringBootApplication public class DemoApplication { 
    public static void main(String[] args) { 
    SpringApplication.run(ConfigApplication.class, args); } } 

那么这个自动装配的过程肯定就是通过@SpringBootApplication这个注解内部实现来完成的。看一下它的源码:

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

@SpringBootApplication这个注解其实是一个复合注解,主要由以下几个部分组成:

  • @Target用于设定注解使用范围,这里表明@SpringBootApplication注解可用于类或者接口上。@Retention表明是运行时注解,@Documented表明这个注解应该被 javadoc工具记录,@Inherited表明继承类也可以使用该注解;
  • @SpringBootConfiguraion表示要加载SpringBoot相关的一些配置;
  • @EnableAutoConfiguration注解用于自动装配,下面细讲;
  • @ComponentScan表明需要扫描的包;

2. @EnableAutoConfiguration注解

这里重点就是这个@EnableAutoConfiguration注解,它也是一个复合注解。看一下它的源码:

@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import(AutoConfigurationImportSelector.class) public @interface EnableAutoConfiguration { 
    .... } 

(1)其中@Import(AutoConfigurationImportSelector.class)这个注解就是用于自动导入AutoConfigurationImportSelector这个类
(2)然后AutoConfigurationImportSelector的selectImports()方法通过SpringFactoriesLoader.loadFactoryNames()扫描所有具有META-INF/spring.factories的jar包。其实每一个可以自动装配的jar里都有一个这样的spring.factories文件。
(3)接着就根据这个spring.factories文件里配置的所有JavaConfig自动配置类的全限定名,找到所有对应的class,然后将所有自动配置类加载到Spring容器中。spring.factories文件示例如下:




# Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 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.cloud.CloudAutoConfiguration,\ org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration .... 

3. application.properties.yml 配置加载

此外,我们通过application.properties.yml配置文件配置的

键值对属性是通过
相关联的某个AutoConfiguration类

(1)比如application.properties.yml中的 server.port=8000这个配置,就是通过 ServletWebServerFactoryAutoConfiguration类加载的,这个类就是专门加载Servlet相关配置的一个自动装配类。看一下它的源码:



@Configuration @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) @ConditionalOnClass(ServletRequest.class) @ConditionalOnWebApplication(type = Type.SERVLET) @EnableConfigurationProperties(ServerProperties.class) @Import({ 
    ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class, ServletWebServerFactoryConfiguration.EmbeddedTomcat.class, ServletWebServerFactoryConfiguration.EmbeddedJetty.class, ServletWebServerFactoryConfiguration.EmbeddedUndertow.class }) public class ServletWebServerFactoryAutoConfiguration { 
    ...... } 

(2)然后这个ServletWebServerFactoryAutoConfiguration类通过@EnableConfigurationProperties({ServerProperties.class})这个注解来将配置文件中的属性注入到ServerProperties中:

@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true) public class ServerProperties { 
    private Integer port; ...... } 

(3)这个ServerProperties类的属性注入完成之后,又加载到了ServletWebServerFactoryAutoConfiguration类中,然后在SpringBoot启动时就可以获取到配置的端口号了。


THE END.

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/229750.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月16日 下午3:58
下一篇 2026年3月16日 下午3:58


相关推荐

  • 快速上手Linux玩转典型应用

    快速上手Linux玩转典型应用

    2022年2月18日
    40
  • keyvaluepair_Dictionary及KeyValuePair使用「建议收藏」

    keyvaluepair_Dictionary及KeyValuePair使用「建议收藏」//////除去数组中的空值和签名参数并以字母a到z的顺序排序//////过滤前的参数组///过滤后的参数组publicstaticDictionaryFilterPara(SortedDictionarydicArrayPre){DictionarydicArray=newDictionary();foreach(KeyValuePairtempindicArrayP…

    2022年7月26日
    7
  • Eclipse中Editor does not contain a main type 解决方法

    Eclipse中Editor does not contain a main type 解决方法Eclipse中Editordoesnotcontainamaintype解决方法1、问题再现2、原因当前的源代码(所有的包)没有被添加到buildpath中src目录出现错误3、解决方法…

    2022年6月1日
    47
  • mysql修改密码方法大全

    mysql修改密码方法大全MySQL 是一个关系型数据库管理系统 在 WEB 应用方面 MySQL 是最好的 RDBMS RelationalDa 关系数据库管理系统 应用软件之一 搭配 PHP 和 Apache 可组成良好的开发环境 因此用的很广泛 很多人都会遇到 MySQL 需要修改密码的情况 比如密码太简单 忘记密码等等 这里我就教大家几种修改 MySQL 密码的方法 这里以修改 root 密码为例 操作系统为 windows 注意 修改 MySQL 是需要有 mysql 里的 root 权限的

    2026年3月17日
    2
  • javascript运动系列第二篇——变速运动

    javascript运动系列第二篇——变速运动原文地址 http www cnblogs com xiaohuochai p 5973556 html 前面的话 前面介绍过匀速运动的实现及注意事项 本文在匀速运动的基础上 更进一步 实现各种变速运动 包括加速运动 减速运动 缓冲运动 重力运动和弹性运动 nbsp 准备工作匀速运动 在原生 javascript 中实现运动的主要工具是定时器 通过设置固定的间隔时间 使元素在确定的间隔时间内实

    2026年3月19日
    3
  • java开发培训_Java培训课程那里好?

    java开发培训_Java培训课程那里好?互联网时代,人们纷纷羡慕IT软件行业的前景和“钱景”。有些行动力较强的更是摩拳擦掌,直接通过参加Java培训班来成功转行这一行业。这些通过Java培训班转行成功的人现在如何了,他们的薪资高吗?没有基础但是想要跟上IT软件行业的发展步伐,选择Java培训班显然是一条有效途径。早几年,IT行业发展刚起步的时候,每一天都有无数家互联网企业诞生,对IT技术人才的需求规模巨大,学员从Java培训班毕业之后迅…

    2022年7月8日
    20

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号