SpringBoot -- 自动化装配源码

自动化装配源码

      • [@EnableAutoConfiguration 注解,开启自动配置的核心注解](#@EnableAutoConfiguration 注解,开启自动配置的核心注解)
        • [@AutoConfigurationPackage 注解](#@AutoConfigurationPackage 注解)
      • [AutoConfigurationImportSelector 类](#AutoConfigurationImportSelector 类)
        • [getAutoConfigurationEntry 方法](#getAutoConfigurationEntry 方法)
        • [getCandidateConfigurations 方法](#getCandidateConfigurations 方法)
      • SpringFactoriesLoader

@EnableAutoConfiguration 注解,开启自动配置的核心注解

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

@EnableAutoConfiguration 包含了@AutoConfigurationPackage 注解和 @Import(AutoConfigurationImportSelector.class) 注解。

@AutoConfigurationPackage 注解

@AutoConfigurationPackage 通过 AutoConfigurationPackages.Registrar 将应用主类所在包及其子包下的所有组件扫描到Spring容器中。

重写这个方法就可以把包注册到spring 容器里面

有4个接口和一个注解都可以把对应类型放到容器里面,上文从源码来看是约定了一个接口,具体如何注册,看实现方式 AutoConfigurationPackages.register(registry, (new PackageImport(metadata)).getPackageName());



放到了定义map中

放到bean工厂,容器启动加载进去指的一说的是这个类,核心类 DefaultListableBeanFactory

从图中可以看到实现了 BeanFactory 接口和 ListableBeanFactory、ConfigurableListableBeanFactory、AutowireCapableBeanFactory 等多个接口。这个类是 Spring 容器的默认实现之一,是一个全功能的 Spring Bean 工厂,提供对 Bean 的完整管理,包括 Bean 的创建、定义、解析依赖、配置等功能

AutoConfigurationImportSelector 类

AutoConfigurationImportSelector 主要作用是收集和加载所有的自动配置类。

java 复制代码
public class AutoConfigurationImportSelector extends ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
        AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }
}
getAutoConfigurationEntry 方法

getAutoConfigurationEntry 方法用于获取所有的自动配置类:

java 复制代码
protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata, AnnotationMetadata annotationMetadata) {
    if (!isEnabled(annotationMetadata)) {
        return EMPTY_ENTRY;
    }
    AnnotationAttributes attributes = getAttributes(annotationMetadata);
    List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
    configurations = removeDuplicates(configurations);
    Set<String> exclusions = getExclusions(annotationMetadata, attributes);
    checkExcludedClasses(configurations, exclusions);
    configurations.removeAll(exclusions);
    configurations = filter(configurations, autoConfigurationMetadata);
    fireAutoConfigurationImportEvents(configurations, exclusions);
    return new AutoConfigurationEntry(configurations, exclusions);
}
getCandidateConfigurations 方法

getCandidateConfigurations 方法从 spring.factories 文件中加载所有的候选配置类:

java 复制代码
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
    List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
    Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
    return configurations;
}

SpringFactoriesLoader


SpringFactoriesLoader.loadFactoryNames 方法会读取 META-INF/spring.factories 文件中的配置,获取所有自动配置类的全限定名。

java 复制代码
public abstract class SpringFactoriesLoader {

    private static final Map<ClassLoader, Map<String, List<String>>> cache = new ConcurrentReferenceHashMap<>();

    public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {
        String factoryClassName = factoryClass.getName();
        return loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
    }


    private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
        MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
        if (result != null) {
            return result;
        } else {
            try {
                Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : 
                ClassLoader.getSystemResources("META-INF/spring.factories");


				// 下面先别管
                MultiValueMap<String, String> result = new LinkedMultiValueMap();


                while(urls.hasMoreElements()) {
                    URL url = (URL)urls.nextElement();
                    UrlResource resource = new UrlResource(url);
                    Properties properties = PropertiesLoaderUtils.loadProperties(resource);
                    Iterator var6 = properties.entrySet().iterator();
					

                    while(var6.hasNext()) {
                        Map.Entry<?, ?> entry = (Map.Entry)var6.next();
                        String factoryClassName = ((String)entry.getKey()).trim();
                        String[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
                        int var10 = var9.length;

                        for(int var11 = 0; var11 < var10; ++var11) {
                            String factoryName = var9[var11];
                            result.add(factoryClassName, factoryName.trim());
                        }
                    }
                }

                cache.put(classLoader, result);
                return result;
            } catch (IOException var13) {
                throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var13);
            }
        }
    }

}

基本就结束了

相关推荐
ZWZhangYu1 分钟前
从 Dify 实践理解大模型上下文缓存
java·后端·spring
众壹新能源科技23 分钟前
逆变器直流开关柜温度监测与预防:红外巡检发现3个120度热点
运维·人工智能·自动化
考虑考虑1 小时前
瀚高数据库
数据库·后端·postgresql
锋行天下2 小时前
DeepSeek写Langgraph就是个大傻逼,一本正经胡说八道
前端·人工智能·后端
万岳软件开发小城3 小时前
AI数字人系统源码如何实现批量视频生成?任务队列与自动化生产流程解析
人工智能·自动化·语音识别·ai数字人小程序·ai数字人系统源码·ai数字人软件开发·ai数字人平台开发
福建佰胜张工3 小时前
深度解析 Allen-Bradley 150-B135NBDA 智能电机控制器:选型、参数与工业应用
运维·数据库·单片机·嵌入式硬件·安全·自动化
小小张说故事3 小时前
Python 的 str 为什么设计成不可变?拆开字符串驻留、字符串池,以及 += 拼接到底慢在哪
后端·python
西瓜拿铁好喝4 小时前
AI 办公和 RPA 不是一回事:自动化与智能化的分工
人工智能·自动化·rpa
AI架构师之家4 小时前
我把 Hermes 这匹"马"养了两周,它干了一件让我有点发毛的事
后端
dpharness4 小时前
块协议用了两周,我把九个坑按顺序记下来了
后端