springboot自动配置原理
springboot自动配置底层原理
selector->selectImports方法(只是返回要被注入容器的类)->调用getAutoConfigurationEntry方法->调用getCandidateConfigurations方法并对其封装->loadFactoryNames()->loadFactoryNames()
return (List)loadSpringFactories(classLoaderToUse).getOrDefault(factoryTypeName, Collections.emptyList());
->
loadSpringFactories(classLoaderToUse)
该方法返回了一个Map<String, List
评估表达式后发现有一个key为
发现它有的值是一个长度138的list,与之前查看到的需要注入的配置类数量相同
再来确定一下
loadSpringFactories(classLoaderToUse).get("org.springframework.boot.autoconfigure.EnableAutoConfiguration")
发现结果果然跟设想的一样

里面有我之前自己创建的一个自动配置类(UserAutoconfig)
此时点进loadSpringFactories方法看他的原理
第一行代码
(Map)cache.get(classLoader)
评估表达式发现结果是null所以运行下面那一坨代码
然后发现关键代码
Enumeration urls = classLoader.getResources("META-INF/spring.factories");
为什么说它是关键代码
评估
classLoader.getResources("META-INF/spring.factories").nextElement()

发现结果居然得到了我的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

浙公网安备 33010602011771号