面试题:SpringBoot 自动装配原理

本文深入解析了SpringBoot的@SpringBootApplication注解,它是程序的入口,包含@SpringBootConfiguration、@EnableAutoConfiguration和@ComponentScan等。@EnableAutoConfiguration启用自动配置,通过@Import导入AutoConfigurationImportSelector,进而扫描并加载所有自动配置类。这些类基于spring.factories文件中的配置,将属性注入到对应的配置类中,如ServerProperties,从而实现应用的自动配置。同时,application.properties.yml配置文件中的属性也能被自动加载并应用于相应配置。
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配置文件配置的<key,value>键值对属性是通过相关联的某个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.

### Spring Boot 自动装配原理 Spring Boot 的自动装配功能是其核心特性之一,旨在简化传统的 Spring 应用程序配置流程。以下是对其工作原理的详细解析: #### 1. **@SpringBootApplication 注解的作用** @SpringBootApplication 是一个复合注解,由以下几个主要部分组成: - @SpringBootConfiguration:表明这是一个 Spring Boot 配置类。 - @EnableAutoConfiguration:启用自动配置机制,这是自动装配的核心所在[^2]。 - @ComponentScan:开启组件扫描,默认会扫描该注解所在的包及其子包内的所有组件。 通过在启动类上标注此注解,开发者无需额外配置即可完成大部分基础设置。 #### 2. **自动装配的核心 —— @EnableAutoConfiguration** @EnableAutoConfiguration 实际上是一个触发器,它通过将 AutoConfigurationImportSelector 类导入到容器中来实现自动化配置的功能[^4]。这个选择器负责收集所有的候选配置类,并决定哪些应该被加载进上下文中。 #### 3. **META-INF/spring.factories 文件的角色** Spring Boot 利用了 Java SPI(Service Provider Interface)机制,在 classpath 下寻找名为 META-INF/spring.factories 的资源文件。该文件定义了一系列扩展点与其对应的实现类映射关系。其中就包含了众多以 EnableAutoConfiguration 开头的关键条目[^3]。 例如: ```properties org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,... ``` 每当项目运行时,Spring Boot 就会读取这些信息并实例化相应的 Configuration Classes。 #### 4. **条件化装配 (Conditional Configuration)** 为了确保只有必要的依赖才会生效,Spring Boot 广泛采用了基于 Condition 的动态决策方式。这意味着即使存在某个特定的技术栈关联的 auto-configurator ,但如果环境不满足预设的前提条件,则不会激活相关联的服务初始化逻辑[^3]。 典型的应用场景包括但不限于检测是否存在某类 jar 包、属性值是否符合预期等等。常用的条件注解有如下几种形式: - @ConditionalOnClass 和 @ConditionalOnMissingClass :分别用于验证指定类型是否可获得或缺失; - @ConditionalOnBean / @ConditionalOnMissingBean : 检验 IOC 容器内部是否有某种 bean 对象注册成功与否; - @ConditionalOnProperty : 根据 application.properties 或 yml 文件里的键名匹配结果判定开关状态; #### 5. **总结** 综上所述,Spring Boot 的自动装配主要是依靠 @EnableAutoConfiguration 注解读入一系列预先定义好的 configuration classes 。再配合灵活多样的 conditional rules 设计思路,从而达到按需定制的效果。这种设计理念不仅减少了人为干预的成本开销,同时也提高了整体系统的稳定性和一致性水平。 --- ### 示例代码片段 以下展示了如何自定义一个简单的自动配置模块: ```java @Configuration @ConditionalOnClass(SomeThirdPartyLibrary.class) public class MyCustomAutoConfig { @Bean public SomeService someService(){ return new DefaultSomeServiceImpl(); } } ``` 在此基础上,还需记得更新 spring.factories 文件内容以便框架识别新增加的支持选项。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值