springboot3.5 自动配置(Auto-Configuration)解析

一、启动入口

1、代码位置:org.springframework.boot.SpringApplication#run

public ConfigurableApplicationContext run(String... args) {
        Startup startup = SpringApplication.Startup.create();
        if (this.properties.isRegisterShutdownHook()) {
            shutdownHook.enableShutdownHookAddition();
        }

        DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();
        ConfigurableApplicationContext context = null;
        this.configureHeadlessProperty();
        SpringApplicationRunListeners listeners = this.getRunListeners(args);
        listeners.starting(bootstrapContext, this.mainApplicationClass);

        try {
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
            ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);
            Banner printedBanner = this.printBanner(environment);
            context = this.createApplicationContext();
            context.setApplicationStartup(this.applicationStartup);
            // 准备上下文
            this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
            // 刷新上下文
            this.refreshContext(context);
            this.afterRefresh(context, applicationArguments);
            startup.started();
            if (this.properties.isLogStartupInfo()) {
                (new StartupInfoLogger(this.mainApplicationClass, environment)).logStarted(this.getApplicationLog(), startup);
            }

            listeners.started(context, startup.timeTakenToStarted());
            this.callRunners(context, applicationArguments);
        } catch (Throwable ex) {
            throw this.handleRunFailure(context, ex, listeners);
        }

        try {
            if (context.isRunning()) {
                listeners.ready(context, startup.ready());
            }

            return context;
        } catch (Throwable ex) {
            throw this.handleRunFailure(context, ex, (SpringApplicationRunListeners)null);
        }
    }

refresh() - 上下文刷新核心方法(org.springframework.context.support.AbstractApplicationContext.refresh()

 

2、配置类处理

配置类处理器

核心解析ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry

	@Override
	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
		int registryId = System.identityHashCode(registry);
		if (this.registriesPostProcessed.contains(registryId)) {
			throw new IllegalStateException(
					"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
		}
		if (this.factoriesPostProcessed.contains(registryId)) {
			throw new IllegalStateException(
					"postProcessBeanFactory already called on this post-processor against " + registry);
		}
		this.registriesPostProcessed.add(registryId);
        // 解析配置类

		processConfigBeanDefinitions(registry);
	}

3、@EnableAutoConfiguration 处理

自动配置选择器

代码位置:AutoConfigurationImportSelector  

    // 1.选择需要导入的配置类
	@Override
	public String[] selectImports(AnnotationMetadata annotationMetadata) {
		if (!isEnabled(annotationMetadata)) {
			return NO_IMPORTS;
		}
		AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
		return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
	}

	protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
		if (!isEnabled(annotationMetadata)) {
			return EMPTY_ENTRY;
		}
		AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 2. 加载候选配置
		List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
		configurations = removeDuplicates(configurations);
		Set<String> exclusions = getExclusions(annotationMetadata, attributes);
		checkExcludedClasses(configurations, exclusions);
		configurations.removeAll(exclusions);
		configurations = getConfigurationClassFilter().filter(configurations);
        // 3、发送导入事件
		fireAutoConfigurationImportEvents(configurations, exclusions);
		return new AutoConfigurationEntry(configurations, exclusions);
	}

4. 加载自动配置类

配置文件位置
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
(Spring Boot 3.x 新位置,替代旧版 spring.factories)

部分内容如下:

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.ImportAutoConfigurationImportSelector#loadFactoryNames

	protected Collection<String> loadFactoryNames(Class<?> source) {
		return ImportCandidates.load(source, getBeanClassLoader()).getCandidates();
	}


    public static ImportCandidates load(Class<?> annotation, ClassLoader classLoader) {
        Assert.notNull(annotation, "'annotation' must not be null");
        ClassLoader classLoaderToUse = decideClassloader(classLoader);

        // 自动导入目录下文件
        String location = String.format("META-INF/spring/%s.imports", annotation.getName());
        Enumeration<URL> urls = findUrlsInClasspath(classLoaderToUse, location);
        List<String> importCandidates = new ArrayList();

        while(urls.hasMoreElements()) {
            URL url = (URL)urls.nextElement();
            importCandidates.addAll(readCandidateConfigurations(url));
        }

        return new ImportCandidates(importCandidates);
    }

5. 条件过滤机智

条件过滤器

核心注解

  • @ConditionalOnClass:类路径存在指定类时生效

  • @ConditionalOnMissingBean:容器中不存在指定Bean时生效

  • @ConditionalOnProperty:配置属性满足条件时生效

如RedisAutoConfiguration

@AutoConfiguration
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {

	@Bean
	@ConditionalOnMissingBean(RedisConnectionDetails.class)
	PropertiesRedisConnectionDetails redisConnectionDetails(RedisProperties properties,
			ObjectProvider<SslBundles> sslBundles) {
		return new PropertiesRedisConnectionDetails(properties, sslBundles.getIfAvailable());
	}

	@Bean
	@ConditionalOnMissingBean(name = "redisTemplate")
	@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
	public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
		RedisTemplate<Object, Object> template = new RedisTemplate<>();
		template.setConnectionFactory(redisConnectionFactory);
		return template;
	}

	@Bean
	@ConditionalOnMissingBean
	@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
	public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
		return new StringRedisTemplate(redisConnectionFactory);
	}

}

过滤过程
org.springframework.boot.autoconfigure.condition.OnClassCondition#getOutcomes

6. Bean 实例化

DefaultListableBeanFactory#preInstantiateSingletons

处理流程

  • 自动配置类被解析为 ConfigurationClass

  • 通过 ConfigurationClassBeanDefinitionReader 注册Bean定义

  • 在 finishBeanFactoryInitialization 阶段实例化单例Bean

代码位置
org.springframework.context.support.AbstractApplicationContext#refresh (9大步骤)

汇总:

关键机制解析

 1. 启动入口: SpringApplication.run()
   │
2. 创建上下文: createApplicationContext()
   │
3. 刷新上下文: AbstractApplicationContext.refresh()
   │
4. 准备BeanFactory((DefaultListableBeanFactory)调用BeanFactoryPostProcessors
   │
5. ConfigurationClassPostProcessor处理配置类
   │
6. 解析@SpringBootApplication → 处理@EnableAutoConfiguration
   │
7. AutoConfigurationImportSelector加载候选配置
   │
8. 从META-INF/spring/*.imports加载配置类
   │
9. 条件过滤: @ConditionalOnClass等条件注解评估
   │
10. 注册有效的自动配置类
   │
11. 实例化自动配置类中的Bean
   │
12. 完成应用启动

二、图接

1、核心流程图

2、springboot 启动调用图解

 

注意事项

  1. Spring Boot 3.x 使用 AutoConfiguration.imports 替代旧版 spring.factories

  2. 使用aot.factories 加速AOT 编译时间要求.

  3. 自动配置类需满足 @AutoConfiguration 注解

  4. 条件注解在 Bean 注册阶段 动态生效

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nextera-void

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值