zl程序教程

您现在的位置是:首页 >  其他

当前栏目

Spring-IoC容器工作原理

2023-03-20 14:58:22 时间

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 ; 
}