要理解自动装配原理,首先要理解BeanDefinition的作用,在BeanDefinition里定义了一些属性,其实就是将Bean的定义信息存储到这个BeanDefinition相应的属性中,后面对Bean的操作就直接对BeanDefinition进行,例如拿到这个BeanDefinition后,可以根据里面的类名、构造函数、构造函数参数,使用反射进行对象创建,BeanDefinition是一个接口,是一个抽象的定义,实际使用的是其实现类,如 ChildBeanDefinition、RootBeanDefinition、GenericBeanDefinition等。
我们都知道@SpringBootApplication注解里面封装了@ComponentScan注解,这个注解默认情况下扫描main函数所在的包路径,把带有@Component, @Configuration, @Service, @Responsitory的类都加载到Spring 容器中,加载过程是怎么样的呢,在@SpringBootApplication注解上面有@EnableAutoConfiguration注解,在这个注解里面又一个很重要的注解,那就是@Import(AutoConfigurationImportSelector.Class), 这个注解的作用是加载META-INF/spring.factories文件里的内容,spring.factories文件里存储的内容是
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ # key,下面的都是value
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.cloud.CloudServiceConnectorsAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
在AutoConfigurationImportSelector类里面有一个getCandidateConfigurations方法,源码如下:
/**
* Return the auto-configuration class names that should be considered. By default
* this method will load candidates using {@link SpringFactoriesLoader} with
* {@link #getSpringFactoriesLoaderFactoryClass()}.
* @param metadata the source metadata
* @param attributes the {@link #getAttributes(AnnotationMetadata) annotation
* attributes}
* @return a list of candidate configurations
*/
protected List getCandidateConfigurations(AnnotationMetadata metadata,
AnnotationAttributes attributes) {
List 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;
}
我们进入loadFactoryNames方法查看:
public static List loadFactoryNames(Class> factoryClass, @Nullable ClassLoader classLoader) {
String factoryClassName = factoryClass.getName();
return (List)loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
}
private static Map> loadSpringFactories(@Nullable ClassLoader classLoader) {
MultiValueMap result = (MultiValueMap)cache.get(classLoader);
if (result != null) {
return result;
} else {
try {
Enumeration urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
LinkedMultiValueMap 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()) {
Entry, ?> entry = (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);
}
}
}
看到classLoader.getResources了吧,它会去找META-INF/spring.factories文件,加载进来,解析文件的内容,根据键值对对应关系,循环遍历spring.factories,把每个键值对解析为一个.property文件,然后再放到一个beanDefinitionMap里面,这个map的key是beanName,value是beanDefinition对象,有了这个beanDefinitionMap,spring会遍历这个map,对每个bean进行实例化(懒加载的除外),这样就得到了autoConfiguration里面每个bean的实例,可以对其进行属性的配置
标签: spring
好文要顶 关注我 收藏该文
成功没有捷径
关注 - 0
粉丝 - 0
0
0
« 上一篇: 股票买到手想卖可以随时都能卖掉吗
posted on 2019-11-30 19:18 成功没有捷径 阅读(0) 评论(0) 编辑 收藏
刷新评论刷新页面返回顶部
发表评论
昵称:
评论内容:
退出
[Ctrl+Enter快捷键提交]
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
【推荐】腾讯云海外1核2G云服务器低至2折,半价续费券限量免费领取!
【推荐】阿里云双11返场来袭,热门产品低至一折等你来抢!
【推荐】天翼云双十一翼降到底,云主机11.11元起,抽奖送大礼
【推荐】流程自动化专家UiBot,体系化教程成就高薪RPA工程师
【活动】京东云服务器_云主机低于1折,低价高性能产品备战双11
【优惠】七牛云采购嘉年华,云存储、CDN等云产品低至1折
相关博文:
· SpringBoot自动装配原理解析
· SpringBoot自动装配原理
· SpringBoot自动装配源码解析
· SpringBoot自动装配的原理
· SpringBoot自动装配原理分析
» 更多推荐...
阿里技术3年大合辑免费电子书一键下载
最新 IT 新闻:
· Infor转型十年启示录:ERP套件厂商为什么要做云平台?
· 开拓创新十余年,中国移动IPv6项目获中国通信学会一等奖
· 微软官宣,打开华为PC爆发式洪流之闸
· 小米再次回购股份:4亿港元回购约4483万股
· 拥抱云端,计算未来
» 更多新闻...
昵称: 成功没有捷径
园龄: 1年11个月
粉丝: 0
关注: 0
|
|||||||||
日 | 一 | 二 | 三 | 四 | 五 | 六 | |||
---|---|---|---|---|---|---|---|---|---|
27 | 28 | 29 | 30 | 31 | 1 | 2 | |||
3 | 4 | 5 | 6 | 7 | 8 | 9 | |||
10 | 11 | 12 | 13 | 14 | 15 | 16 | |||
17 | 18 | 19 | 20 | 21 | 22 | 23 | |||
24 | 25 | 26 | 27 | 28 | 29 | 30 | |||
1 | 2 | 3 | 4 | 5 | 6 | 7 |
Powered by: 博客园 模板提供:沪江博客 Copyright © 2019 成功没有捷径
Powered by .NET Core 3.0.0 on Linux