Spring-IoC容器工作原理
IoC容器工作原理
1. 创建beanFactory
容器底层用DefaultListableBeanFactory,即实现了BeanDe finitionRegistry,又实现了BeanFactory java配置 :
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
this() 方 法 ----> 调父类无参构造器
public GenericApplicationContext(){
this.beanFactory = new DefaultListableBeanFactory();
}
在 容 器 启 动 之 前 就 创 建 beanFactory xml 配 置 :
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("Spring.xml");
调 refresh() 后 ,即容器启动过程中创建 beanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
> refreshBeanFactory(); // AbstractApplicationContext#refreshBeanFactory
先创建DefaultListableBeanFactory实例,然后解析xml配置文件,注册bean到beanFactory ,最后再将beanFactory赋值给容器
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
// 定制beanFactory,设置参数
customizeBeanFactory(beanFactory);
// 注册spring的xml配置的bean到beanFactory,此时容器还未指定beanbeanFactory
loadBeanDefinitions(beanFactory);
// 给容器指定beanFactory
synchronized(this.beanFactoryMonitor){
this.beanFactory = beanFactory;
}
2. 注册bean
核心原理 : 通过调用registerBeanDefinition方法将bean的beanName----beanDe finition注册到beanFactory
DefaultListableBeanFactory#registerBeanDefinition //实现了BeanDefinitionRegistry
> beanDefinitionMap.put(beanName,beanDefinition); //缓存beanDefinition
代码示例 :
// 拿到工厂 实现了BeanDefinitionRegistry
DefaultListableBeanFactorybeanFactory = context.getDefaultListableBeanFactory();
// 创建一个beanDefinition
RootBeanDefinitionbeanDefinition = newRootBeanDefinition(User.class);
// 注册
beanFactory.registerBeanDefinition("user",beanDefinition);
java配置 : 容器启动过程中,会调用ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry解析注解,注册bean
invokeBeanFactoryPostProcessors(beanFactory); // 解析注解,注册bean
> ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry
ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry中有两个很重要的方法
// 解析配置类@ComponentScan(bean注册到容器)@Import @ImportResource @Bean
parser.parse(candidates);
// 注册bean到容器
// 注册实现了ImportSelector的bean
// 方法bean注册到容器
// @ImportResource("spring.xml")配置的bean注册到容器
// 实现ImportBeanDefinitionRegistrar的bean注册到容器
this.reader.loadBeanDefinitions(configClasses);
解析注解
parser.parse(candidates);
> ConfigurationClassParser#processConfigurationClass
> ConfigurationClassParser#doProcessConfigurationClass
ConfigurationClassParser#doProcessConfigurationClass会处理@ComponentScan,@Import,@ImportResource,@Bean @ComponentScan会将@Component修饰的bean注入到容器
ClassPathBeanDefinitionScanner#doScan
>
// 找到@Component修饰的类的beanDefiniton集合
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
// 注册bean
registerBeanDefinition(definitionHolder,this.registry);
注册bean
this.reader.loadBeanDefinitions(configClasses)
> ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForConfigurationClass
if(configClass.isImported()){
// implementsImportSelector的bean注册
registerBeanDefinitionForImportedConfigurationClass(configClass);
}
for(BeanMethodbeanMethod : configClass.getBeanMethods()){
// 方法bean注册到容器
loadBeanDefinitionsForBeanMethod(beanMethod);
}
// @ImportResource("spring.xml")配置的bean注册到容器loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
//实现ImportBeanDefinitionRegistrar的bean注册到容器
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
xml配置:
ConfigurableListableBeanFactorybeanFactory = obtainFreshBeanFactory();
> refreshBeanFactory(); // AbstractApplicationContext#refreshBeanFactory
将beanFactory赋值给容器之前解析xml,并且注册bean
DefaultListableBeanFactorybeanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
// 定制beanFactory,设置参数
customizeBeanFactory(beanFactory);
// 注册spring的xml配置的bean到beanFactory,此时容器还未指定beanbeanFactoryloadBeanDefinitions(beanFactory);
// 给容器指定beanFactory
synchronized(this.beanFactoryMonitor){
this.beanFactory = beanFactory ;
}
解析xml loadBeanDefinitions(beanFactory)最终会调DefaultBeanDefinitionDocumentReader#doRegisterBeanDefinitions
// 注册spring的xml配置的bean到beanFactory,此时容器还未指定beanbeanFactory
loadBeanDefinitions(beanFactory);
> DefaultBeanDefinitionDocumentReader#doRegisterBeanDefinitions
preProcessXml(root);
parseBeanDefinitions(root,this.delegate); // 解析xml
postProcessXml(root);
> DefaultBeanDefinitionDocumentReader#parseDefaultElement
else if(delegate.nodeNameEquals(ele,BEAN_ELEMENT)){
// 解析bean
processBeanDefinition(ele,delegate);
}
> DefaultBeanDefinitionDocumentReader#processBeanDefinition
// 注册最后修饰后的实例beanDefinition
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder,
getReaderContext().getRegistry());
注册bean BeanDefinitionReaderUtils#registerBeanDefinition中会注册bean
// 注册beanDefiniton
registry.registerBeanDefinition(beanName,definitionHolder.getBeanDefinition());
3. 创建bean实例
容器启动过程中会实例化非懒加载单例bean,通过AbstractBeanFactory创建bean的实例
AbstractApplicationContext#refresh
// Instantiateallremaining(non-lazy-init)singletons.
// 实例化所有剩余的(非懒加载)单例 。
> finishBeanFactoryInitialization(beanFactory);
> AbstractApplicationContext#getBean(String)
调用context.getBean(name)获取bean实例,实际会去调用AbstractBeanFactory的getBean()方法 。
AbstractApplicationContext #getBean(String)
> AbstractBeanFactory #getBean(String)
调用AbstractBeanFactory#doGetBean,先从singletonObjects中去获取bean
// 转换对应的beanName
// 1. 带 & 前缀的去掉前缀
// 2. 从aliasMap中找name对应id,bean没有配id就用name
finalStringbeanName = transformedBeanName(name);
// 先从缓存singletonObjects中找,没有则去创建
// 处理循环依赖的问题,比如A ->B,B->A
ObjectsharedInstance = getSingleton(beanName);
// 判断单例
if(mbd.isSingleton()){
sharedInstance = getSingleton(beanName,()-> {
return createBean(beanName,mbd,args);
});
bean = getObjectForBeanInstance(sharedInstance,name,beanName,mbd); }
调用AbstractAutowireCapableBeanFactory#doCreateBean返回bean
AbstractAutowireCapableBeanFactory#createBean(String,RootBeanDefinition,Object[])
// 返回bean实例
> Object beanInstance = doCreateBean(beanName,mbdToUse,args);
实例化bean 调用AbstractAutowireCapableBeanFactory#doCreateBean
/**
* 第2次调用后置处理器
* 创建bean实例,并将实例放在包装类BeanWrapper中返回
* 1. 通过工厂方法创建bean实例
* 2. 通过构造方法自动注入创建bean实例
* 3. 通过无参构造器创建bean实例
*/
instanceWrapper = createBeanInstance(beanName,mbd,args);
finalObjectbean = instanceWrapper.getWrappedInstance();
填充bean
// 填充bean设置属性
InstantiationAwareBeanPostProcessors
// 第5次,第6次调用后置处理器 注入依赖
populateBean(beanName,mbd,instanceWrapper);
初始化bean
// 初始化bean
exposedObject = initializeBean(beanName,exposedObject,mbd);
返回bean
// 返回类型判断FactoryBeanBeanFactroy
bean = getObjectForBeanInstance(sharedInstance,name,beanName,mbd);>
//涉及FactoryBean的判断,直接返回普通bean的条件类型是否是FactoryBean || name首字符是否是 &
if(!(beanInstanceinstanceofFactoryBean)|| BeanFactoryUtils.isFactoryDereference(name){
return beanInstance ;
}
相关文章
- 苹果态度全面反转:不想升级iOS15?那就断更iOS 14
- 15.3 RC发布!苹果:快升级iOS 15 原因很重要
- 苹果突然变脸!彻底停更iOS 14、强推iOS 15:回应让人难接受
- 支付宝集五福开抢玩法变了 集齐更容易
- 支付宝集五福开抢!教你马上开始集五福
- 2022支付宝集五福官方攻略:1000多商家发福卡
- 苹果开后门,iOS15可降级iOS14.1
- 没给出任何原因 iPhone 13全系不再支持“电话降噪”功能
- 苹果鼓励用户升级iOS 15:已取消留在iOS 14选项
- 12306电子临时乘车身份证明今日上线!官方详解:简单五步申领
- 已经厌倦了微博公众号?教你玩转经典的RSS订阅
- 一键已读等到了!支付宝上线消息“刷子” 网友:强迫症治好了
- 掌握表格设计,就掌握 B 端设计的半壁江山!
- 苹果强迫用户升级iOS 15 关闭所有老版本更新 Bug不修复
- iOS 15安装比例较前两代系统退步 苹果出手:终止iOS 14更新倒逼升级
- 这个能一秒换天的超强P图软件现在可以白嫖了
- iOS 15连发两个版本!升级建议来了
- 尽快升级!苹果发布iOS 15.2.1:修复iPhone、iPad重要大漏洞
- 把iOS 15做进浏览器?这款小工具香疯了
- 企业微信活跃用户达1.8亿!微信客服正式接入