SpringBoot自动配置源码之SpringBoot3.1.1

备注:关键代码是注释标记了debug主线的

1.使用 @EnableAutoConfiguration 启用自动配置

1.1 程序入口

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

1.2 启动自动配置注解

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
//debug主线
@EnableAutoConfiguration
public @interface SpringBootApplication {
    //omit...
}
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
//debug主线
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
	//omit...
}

2.从 spring-boot-autoconfigure.jar 文件的 AutoConfiguration.imports 中获取所有自动配置类

//自动配置导入选择器
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
    //omit...
    //为什么是这个方法?因为AutoConfigurationImportSelector实现了DeferredImportSelector extends ImportSelector,
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
    	//如果没有启动自动配置
        if(!this.isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        } else {
            //debug主线:获取自动配置类
            AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
            return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
        }
    }
    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if(!this.isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        } else {
            //获取启动类注解属性
            AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
            //debug主线:从META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件获取所有全限定自动配置类名
            List < String > configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
            configurations = this.removeDuplicates(configurations);
            Set < String > exclusions = this.getExclusions(annotationMetadata, attributes);
            this.checkExcludedClasses(configurations, exclusions);
            configurations.removeAll(exclusions);
            configurations = this.getConfigurationClassFilter().filter(configurations);
            this.fireAutoConfigurationImportEvents(configurations, exclusions);
            return new AutoConfigurationEntry(configurations, exclusions);
        }
    }
    //omit...
}
//自动配置导入选择器
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
    //omit...
    protected List < String > getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
        //debug主线:加载自动配置类,并将它们作为字符串列表存储在 configurations 变量中
        List < String > configurations = ImportCandidates.load(AutoConfiguration.class, this.getBeanClassLoader()).getCandidates();
        Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports. If you are using a custom packaging, make sure that file is correct.");
        return configurations;
    }
   //omit...
}
//提供对这些候选自动配置类的迭代访问
public final class ImportCandidates implements Iterable < String > {
    //omit...
    public static ImportCandidates load(Class <? > annotation, ClassLoader classLoader) {
            Assert.notNull(annotation, "'annotation' must not be null");
            ClassLoader classLoaderToUse = decideClassloader(classLoader);
            //最终得到:META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
            //此文件包含了146个开发常用的AutoConfiguration类,
            String location = String.format("META-INF/spring/%s.imports", annotation.getName());
            //从你的spring-boot-autoconfigure-3.1.1.jar下面classpath找到这个位置
            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);
        }
        //omit...
}

3.从自动配置类集合中移除启动类中排除的类

//自动配置导入选择器
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
    //omit...
    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
            if(!this.isEnabled(annotationMetadata)) {
                return EMPTY_ENTRY;
            } else {
                AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
                List < String > configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
                configurations = this.removeDuplicates(configurations);
                //支线:获取你启动类注解添加的排除类属性,@SpringBootApplication(exclude = ...,excludeName = ...)
                Set < String > exclusions = this.getExclusions(annotationMetadata, attributes);
                this.checkExcludedClasses(configurations, exclusions);
                //移除你指定需要排除的类如果有
                configurations.removeAll(exclusions);
                configurations = this.getConfigurationClassFilter().filter(configurations);
                this.fireAutoConfigurationImportEvents(configurations, exclusions);
                return new AutoConfigurationEntry(configurations, exclusions);
            }
        }
        //omit...
}

4.过滤掉不符合 @ConditionalOnXXX 相关注解条件的自动配置类

//自动配置导入选择器
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
    //omit...
    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
            if(!this.isEnabled(annotationMetadata)) {
                return EMPTY_ENTRY;
            } else {
                AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
                List < String > configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
                configurations = this.removeDuplicates(configurations);
                Set < String > exclusions = this.getExclusions(annotationMetadata, attributes);
                this.checkExcludedClasses(configurations, exclusions);
                configurations.removeAll(exclusions);
                //支线:从所需的自动配置类集合中过滤掉那些带有不满足 @ConditionalOnXXX 相关注解条件的自动配置类
                /**
                 * 这样做是因为只有在你使用了相关组件时,才会为你引入相应的自动配置。
                 * 举个例子:在自动配置类集合中存在一个叫RabbitAutoConfiguration的自动配置类,并且该类上存在 @ConditionalOnClass({RabbitTemplate.class, Channel.class}) 注解。
                 * 如果你想使用 Rabbit 组件,那么你需要在 Maven 中引入 rabbitmq-starter 依赖。引入了 rabbitmq-starter 之后,你还需要将 RabbitTemplate 作为 Bean 加载到 Spring 容器中。
                 * 一旦容器中存在了 RabbitTemplate,那么这个自动配置类就会自动生效,
                 * 一个空项目自然不会引入这么多外部starter,所以你最终生效的自动配置类146个可能过滤后就只有不到30个会注入到容器中
                 */
                configurations = this.getConfigurationClassFilter().filter(configurations);
                this.fireAutoConfigurationImportEvents(configurations, exclusions);
                return new AutoConfigurationEntry(configurations, exclusions);
            }
        }
        //omit...
}

5.将符合条件的自动配置类注入到单例对象 ConcurrentHashMap 中

//自动配置导入选择器
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
    //omit...
    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
            if(!this.isEnabled(annotationMetadata)) {
                return EMPTY_ENTRY;
            } else {
                AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
                List < String > configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
                configurations = this.removeDuplicates(configurations);
                Set < String > exclusions = this.getExclusions(annotationMetadata, attributes);
                this.checkExcludedClasses(configurations, exclusions);
                configurations.removeAll(exclusions);
                configurations = this.getConfigurationClassFilter().filter(configurations);
                //debug主线:触发自动导入事件
                this.fireAutoConfigurationImportEvents(configurations, exclusions);
                return new AutoConfigurationEntry(configurations, exclusions);
            }
        }
        /**
         * 触发自动配置导入事件,并通知所有的自动配置导入监听器。
         *
         * @param configurations 自动配置类列表
         * @param exclusions     排除的自动配置类列表
         */
    private void fireAutoConfigurationImportEvents(List < String > configurations, Set < String > exclusions) {
            // 获取所有的自动配置导入监听器
            List < AutoConfigurationImportListener > listeners = getAutoConfigurationImportListeners();
            // 如果监听器列表不为空
            if(!listeners.isEmpty()) {
                // 创建一个 AutoConfigurationImportEvent 事件对象,包含当前对象(即 this)、自动配置类列表和排除的自动配置类列表
                AutoConfigurationImportEvent event = new AutoConfigurationImportEvent(this, configurations, exclusions);
                // 遍历监听器列表
                for(AutoConfigurationImportListener listener: listeners) {
                    // 对监听器进行调用前的准备操作(如调用相关的 Aware 方法)
                    invokeAwareMethods(listener);
                    //debug主线:调用每个监听器的 onAutoConfigurationImportEvent 方法,将事件对象作为参数传递给监听器,通知其处理自动配置导入事件
                    listener.onAutoConfigurationImportEvent(event);
                }
            }
        }
        //omit...
}
/**
 * 自动配置导入监听器接口
 */
@FunctionalInterface
public interface AutoConfigurationImportListener extends EventListener {

	/**
	 * debug主线:处理自动配置导入事件。
	 * @param event 要响应的事件
	 */
	void onAutoConfigurationImportEvent(AutoConfigurationImportEvent event);

}
/**
 * ConditionEvaluationReportAutoConfigurationImportListener 类是一个实现了 AutoConfigurationImportListener 接口和 BeanFactoryAware 接口的条件评估报告自动配置导入监听器。
 */
class ConditionEvaluationReportAutoConfigurationImportListener implements AutoConfigurationImportListener, BeanFactoryAware {
	//omit...
  	private ConfigurableListableBeanFactory beanFactory;

    /**
     * 处理自动配置导入事件。
     * @param event 要响应的事件
     */
    @Override
    public void onAutoConfigurationImportEvent(AutoConfigurationImportEvent event) {
        // 检查是否已经设置了 beanFactory
        if (this.beanFactory != null) {
            // debug主线:获取条件评估报告实例
            ConditionEvaluationReport report = ConditionEvaluationReport.get(this.beanFactory);
            // 记录评估候选配置
            report.recordEvaluationCandidates(event.getCandidateConfigurations());
            // 记录排除的自动配置
            report.recordExclusions(event.getExclusions());
        }
    }
  //omit...
}     
public final class ConditionEvaluationReport {
    /**
     * 根据指定的 BeanFactory 获取 ConditionEvaluationReport。
     * @param beanFactory BeanFactory 实例
     * @return 存在的 ConditionEvaluationReport 实例,如果不存在则创建一个新实例
     */
    public static ConditionEvaluationReport get(ConfigurableListableBeanFactory beanFactory) {
            synchronized(beanFactory) {
                ConditionEvaluationReport report;
                // 检查是否已经存在单例实例
                if(beanFactory.containsSingleton(BEAN_NAME)) {
                    // 如果存在,则获取现有的 ConditionEvaluationReport 实例
                    report = beanFactory.getBean(BEAN_NAME, ConditionEvaluationReport.class);
                } else {
                    // 如果不存在,则创建一个新的 ConditionEvaluationReport 实例
                    report = new ConditionEvaluationReport();
                    // debug主线:将新实例注册为单例实例
                    beanFactory.registerSingleton(BEAN_NAME, report);
                }
                // 定位父级 BeanFactory 的 ConditionEvaluationReport
                locateParent(beanFactory.getParentBeanFactory(), report);
                // 返回 ConditionEvaluationReport 实例
                return report;
            }
        }
        // 省略其他代码...
}
}
/**
 * SingletonBeanRegistry 接口定义了管理单例 Bean 的方法。
 */
public interface SingletonBeanRegistry {
    /**
     * debug主线:注册一个单例对象。
     * @param beanName       Bean 的名称
     * @param singletonObject 单例对象实例
     */
    void registerSingleton(String beanName, Object singletonObject);

    /**
     * 获取指定名称的单例对象。
     * @param beanName Bean 的名称
     * @return 单例对象实例,如果不存在则返回 null
     */
    @Nullable
    Object getSingleton(String beanName);

    /**
     * 检查是否存在指定名称的单例对象。
     * @param beanName Bean 的名称
     * @return 如果存在指定名称的单例对象则返回 true,否则返回 false
     */
    boolean containsSingleton(String beanName);

    /**
     * 获取所有注册的单例 Bean 的名称。
     * @return 单例 Bean 的名称数组
     */
    String[] getSingletonNames();

    /**
     * 获取注册的单例 Bean 的数量。
     * @return 单例 Bean 的数量
     */
    int getSingletonCount();

    /**
     * 获取单例对象的互斥锁。
     * @return 单例对象的互斥锁
     */
    Object getSingletonMutex();
}

/**
 * DefaultListableBeanFactory 是一个实现了 ConfigurableListableBeanFactory、BeanDefinitionRegistry 接口的类,
 * 继承自 AbstractAutowireCapableBeanFactory,用于注册单例对象的默认可列举 Bean 工厂。
 */
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
    // 省略其他代码...
	
    /**
     * 注册一个单例对象。
     * @param beanName       Bean 的名称
     * @param singletonObject 单例对象实例
     * @throws IllegalStateException 如果已存在同名的单例对象则抛出异常
     */
    public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
        // 主线debug:调用父类DefaultSingletonBeanRegistry的 registerSingleton 方法,将单例对象注册到父类的 singletonObjects 中
        super.registerSingleton(beanName, singletonObject);

        // 更新手动注册的单例名称集合
        this.updateManualSingletonNames(set -> {
            set.add(beanName);
        }, set -> {
            // 检查该 Bean 名称是否已经存在于 beanDefinitionMap 中,如果存在则返回 false
            return !this.beanDefinitionMap.containsKey(beanName);
        });

        // 清除类型缓存
        this.clearByTypeCache();
    }

    // 省略其他代码...
}

/**
 * DefaultSingletonBeanRegistry 是一个实现了 SingletonBeanRegistry 接口的类,
 * 继承自 SimpleAliasRegistry,用于注册和管理单例 Bean 的默认单例 Bean 注册表。
 */
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
    // 省略其他代码...
    
	//存储单例对象的映射
	private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256);
    /**
     * 注册一个单例对象。
     * @param beanName       Bean 的名称
     * @param singletonObject 单例对象实例
     * @throws IllegalStateException 如果已存在同名的单例对象则抛出异常
     */
    public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
        // 检查 beanName 是否为 null
        Assert.notNull(beanName, "Bean name must not be null");
        // 检查 singletonObject 是否为 null
        Assert.notNull(singletonObject, "Singleton object must not be null");

        // 对 singletonObjects 进行同步操作
        synchronized (this.singletonObjects) {
            // 检查是否已存在同名的单例对象
            Object oldObject = this.singletonObjects.get(beanName);
            if (oldObject != null) {
                // 如果已存在同名的单例对象,则抛出 IllegalStateException 异常
                throw new IllegalStateException("Could not register object [" + singletonObject + "] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
            } else {
                // 主线debug:否则将单例对象添加到 singletonObjects 中
                this.addSingleton(beanName, singletonObject);
            }
        }
    }

    /**
     * 添加一个单例对象到单例对象映射中。
     * @param beanName        Bean 的名称
     * @param singletonObject 单例对象实例
     */
    protected void addSingleton(String beanName, Object singletonObject) {
        // 对 singletonObjects 进行同步操作
        synchronized (this.singletonObjects) {
            // 将单例对象添加到 singletonObjects 中
            this.singletonObjects.put(beanName, singletonObject);
            // 从 singletonFactories 中移除对应的单例工厂对象
            this.singletonFactories.remove(beanName);
            // 从 earlySingletonObjects 中移除对应的早期单例对象
            // 这一步是为了解决循环依赖的三级缓存问题
            // 详细原理可参考 Spring 的循环依赖解决机制
            this.earlySingletonObjects.remove(beanName);
            // 将 beanName 添加到 registeredSingletons 中,标记该 Bean 已注册为单例
            this.registeredSingletons.add(beanName);
        }
    }

    // 省略其他代码...
}

至此SpringBoot应用上下文创建阶段之自动配置类:从文件中读取、筛选、到加载到ConcurrentHashMap的代码已经跑完,

剩下的就是SpringBootApplication.run方法里面的应用上下文刷新阶段,可查看启动程序run方法里面的this.refreshContext(context);方法,跟到AbstractApplicationContext.refresh()方法,包括创建 Web 服务器、加载应用程序的配置、bean工厂处理、初始化各种组件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值