springboot自动配置原理

springboot自动配置底层原理

selector->selectImports方法(只是返回要被注入容器的类)->调用getAutoConfigurationEntry方法->调用getCandidateConfigurations方法并对其封装->loadFactoryNames()->loadFactoryNames()

return (List)loadSpringFactories(classLoaderToUse).getOrDefault(factoryTypeName, Collections.emptyList());

->

loadSpringFactories(classLoaderToUse)

该方法返回了一个Map<String, List>

评估表达式后发现有一个key为image

发现它有的值是一个长度138的list,与之前查看到的需要注入的配置类数量相同

再来确定一下

loadSpringFactories(classLoaderToUse).get("org.springframework.boot.autoconfigure.EnableAutoConfiguration")

发现结果果然跟设想的一样

image

里面有我之前自己创建的一个自动配置类(UserAutoconfig)

此时点进loadSpringFactories方法看他的原理

第一行代码

(Map)cache.get(classLoader)

评估表达式发现结果是null所以运行下面那一坨代码

然后发现关键代码

Enumeration urls = classLoader.getResources("META-INF/spring.factories");

为什么说它是关键代码

评估

classLoader.getResources("META-INF/spring.factories").nextElement()

image

发现结果居然得到了我的spring.factories文件的绝对地址

所以就是通过classloader的getResources方法来获取我的spring.factories文件绝对地址

今日总结:selectImports方法只是起个桥梁作用,它用getAutoConfigurationEntry返回的对getCandidateConfigurations方法返回的自动配置类的全限定名的List进行封装的AutoConfigurationImportSelector.AutoConfigurationEntry,autoConfigurationEntry有个etConfigurations()方法,目前还没点进去看,不过一个是返回所有配置类全限定名称的list,使用然后调用工具方法StringUtils.toStringArray方法把list转换成字符串数组,返回给容器交给容器来实例化

所以说:

getAutoConfigurationEntry对全限定名集进行封装

getCandidateConfigurations获取全限定名集

所以就有理由点进getCandidateConfigurations方法,loadFactoryNames只是判断传进去的classloader是否为null,里面有一个loadSpringFactories方法可以返回一个Enumeration用来枚举出所有的全限定名调用的是classLoader.getResources("META-INF/spring.factories")而在这之前会判断缓存里面是否有已经存在的结果

Map<String, List<String>> result = (Map)cache.get(classLoader);
if (result != null) {
    return result;
}

如果有直接返回没有的话会在进行上述操作后进行cache.put(classLoader, result);把获取到的结果放到缓存中去

all in all 调用classLoader.getResources获取meta-inf/spring.factories

posted @ 2022-04-07 21:33  dronff  阅读(46)  评论(0)    收藏  举报