设为首页 加入收藏

TOP

Spring Boot 自动配置的 “魔法” 是如何实现的?(四)
2018-06-10 15:40:27 】 浏览:869
Tags:Spring Boot 自动 配置 魔法 如何 实现

String[] excludeName() default {}; }

我们发现@Import(Spring 提供的一个注解,可以导入配置类或者Bean到当前类中)导入了EnableAutoConfigurationImportSelector类,根据名字来看,它应该就是我们要找到的目标了。不过查看它的源码发现它已经被Deprecated了,而官方API中告知我们去查看它的父类AutoConfigurationImportSelector。

/** @deprecated */
@Deprecated
public class EnableAutoConfigurationImportSelector extends AutoConfigurationImportSelector {
    public EnableAutoConfigurationImportSelector() {
    }
    protected boolean isEnabled(AnnotationMetadata metadata) {
        return this.getClass().equals(EnableAutoConfigurationImportSelector.class)?((Boolean)this.getEnvironment().getProperty("spring.boot.enableautoconfiguration", Boolean.class, Boolean.valueOf(true))).booleanValue():true;
    }
}

由于AutoConfigurationImportSelector的源码太长了,这里我只截出关键的地方,显然方法selectImports是选择自动配置的主入口,它调用了其他的几个方法来加载元数据等信息,最后返回一个包含许多自动配置类信息的字符串数组。

public String[] selectImports(AnnotationMetadata annotationMetadata) {
    if(!this.isEnabled(annotationMetadata)) {
        return NO_IMPORTS;
    } else {
        try {
            AutoConfigurationMetadata ex = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
            AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
            List configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
            configurations = this.removeDuplicates(configurations);
            configurations = this.sort(configurations, ex);
            Set exclusions = this.getExclusions(annotationMetadata, attributes);
            this.checkExcludedClasses(configurations, exclusions);
            configurations.removeAll(exclusions);
            configurations = this.filter(configurations, ex);
            this.fireAutoConfigurationImportEvents(configurations, exclusions);
            return (String[])configurations.toArray(new String[configurations.size()]);
        } catch (IOException var6) {
            throw new IllegalStateException(var6);
        }
    }
}

重点在于方法getCandidateConfigurations()返回了自动配置类的信息列表,而它通过调用SpringFactoriesLoader.loadFactoryNames()来扫描加载含有META-INF/spring.factories文件的jar包,该文件记录了具有哪些自动配置类。(建议还是用IDE去看源码吧,这些源码单行实在太长了,估计文章中的观看效果很差)

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
    List configurations = SpringFactoriesLoader
    									.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.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;
}
	
public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
    String factoryClassName = factoryClass.getName();
    try {
        Enumeration ex = classLoader != null?classLoader.getResources("META-INF/spring.factories"):ClassLoader.getSystemResources("META-INF/spring.factories");
        ArrayList result = new ArrayList();
        while(ex.hasMoreElements()) {
            URL url = (URL)ex.nextElement();
            Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
            String factoryClassNames = properties.getProperty(factoryClassName);
            result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringAr  
		
Spring Boot 自动配置的 “魔法” 是如何实现的?(四) https://www.cppentry.com/bencandy.php?fid=76&id=170268

首页 上一页 1 2 3 4 5 6 7 下一页 尾页 4/7/7
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇linux 如何更改网卡 MAC 地址 下一篇JDK 源码阅读 : FileDescriptor