SpringBoot系列--自动装配原理1

一、自动配置原理

1、原理图

www.processon.com/diagraming/6072e...

2、源码入手

  • SpringBootApplication

SpringBoot系列--自动装配原理
注解说明:
@Target(ElementType.TYPE)//设置当前注解可以标注在哪
@Retention(RetentionPolicy.RUNTIME)//标注注解的类编译以什么方式保留–运行时类,会被jvm加载
@Documented //生成java doc注解信息
@Inherited //是否会被继承
@SpringBootConfiguration //标注在某个类上,标识这是一个SpringBoot配置类
@EnableAutoConfiguration //标识这是一个配置类;配置类也是容器中的一个组件
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), //扫描包
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
FilterType:spring对外提供的扩展类,可以按照我们的意愿进行排除
AutoConfigurationExcludeFilter:排除所有配置类并且是自动配置类中里面的其中一个

我们进入注解—>@EnableAutoConfiguration

SpringBoot系列--自动装配原理

@AutoConfigurationPackage,作用是将当前配置类所在的包保存在BasePackages的Bean中,供Spring内部使用

@Import 关键注解
可以看到,在@EnableAutoConfiguration注解内使用到了@import注解来完成导入配置的功能,而EnableAutoConfigurationImportSelector 实现了DeferredImportSelectorSpring内部在解析@Import注解时会调用getAutoConfigurationEntry方法

SpringBoot系列--自动装配原理
如下代码的getCandidateConfigurations方法

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方法中的SpringFactoriesLoader.loadFactoryNames.loadFactoryNames.loadSpringFactories方法中进行扫描具有META-INF/spring.factories文件的jar包。

public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
        String factoryTypeName = factoryType.getName();
        return loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
    }

    private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
        MultiValueMap<String, String> result = cache.get(classLoader);
        if (result != null) {
            return result;
        }

        try {
            Enumeration<URL> urls = (classLoader != null ?
                    classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
                    ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
            result = new LinkedMultiValueMap<>();
            while (urls.hasMoreElements()) {
                URL url = urls.nextElement();
                UrlResource resource = new UrlResource(url);
                Properties properties = PropertiesLoaderUtils.loadProperties(resource);
                for (Map.Entry<?, ?> entry : properties.entrySet()) {
                    String factoryTypeName = ((String) entry.getKey()).trim();
                    for (String factoryImplementationName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {
                        result.add(factoryTypeName, factoryImplementationName.trim());
                    }
                }
            }
            cache.put(classLoader, result);
            return result;
        }
        catch (IOException ex) {
            throw new IllegalArgumentException("Unable to load factories from location [" +
                    FACTORIES_RESOURCE_LOCATION + "]", ex);
        }
    }

@EnableAutoConfiguration注解通过@SpringBootApplication被间接的标记在了Spring Boot的启动类上。在SpringApplication.run(…)的内部就会执行selectImports()方法,找到所有JavaConfig自动配置类的全限定名对应的class,然后将所有自动配置类加载到Spring容器中

如下为SpringBoot自动配置原理图
自动配置原理图

本作品采用《CC 协议》,转载必须注明作者和本文链接
Kuroko
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!