Spring IOC 源码-bean解析 博客分类: spring springioc源码
spring bean的解析及创建过程:
(1)元数据层(xml anotation )
(2)逻辑定义层(解析元素,将结果汇总到beandefination,定义对象初始化逻辑和依赖关系,发生在Beanfactory初始化时候)
(3)应用层(bean加载 将bean初始化成对象,发生在getBean时候)
1、元数据到BeanDefination的解析过程
DefaultListableFactory 的registerBeanDefinition方法将从xml中解析的beanName和beanDefinition(GenericBeanDefinition)注册到一个在内存中的map:beanDefinitionMap
1)bean创建的入口:
2)创建beanFactory的构造方法中会同时会调用XmlBeanDefinitionReader的loadBeanDefinitions方法,去读取Xm配置文件,加载beanDefination
3)loadBeanDefinitions方法会调用doLoadBeanDefinitions方法
4)doLoadBeanDefinitions方法首先把xm文件 解析成Document对象,再调用registerBeanDefinitions方法,将document对象和resource作为参数
5)再来看registerBeanDefinitions方法,这个方法最关键的地方在BeanDefinitionDocumentReader的registerBeanDefinitions
6)BeanDefinitionDocumentReader的registerBeanDefinitions,BeanDefinitionDocumentReader是一个接口 有以下几个实现类:DefaultBeanDefinitionDocumentReader
6)DefaultBeanDefinitionDocumentReader中调用doRegisterBeanDefinitions方法
7)parseBeanDefinitions 中解析xm元素,我们比较关注的是对于bean以及property的解析,此处进去以后会调用,依次解析bean的属性,将解析好的属性放到AbstractBeanDefinition中
8)AbstractBeanDefinition有以下子类,使用的是GenericBeanDefinition,最终将得到的BeanDefinition和beanClass统一放到BeanDefinitionHolder中去
9)BeanDefinitionHolder的结构是:
10)bean解析完成后会调用BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
11)registerBeanDefinition方法的实现如下:
其中register的定义-BeanDefinitionRegistry 是一个接口,主要的实现类包括:
12)进入到DefaultListableBeanFactory:在这个方法中将beanDefinition最终注册到beanDefinitionMap里面去,此处并没有对 bean进行实例化,
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
synchronized (this.beanDefinitionMap) {
Object oldBeanDefinition = this.beanDefinitionMap.get(beanName);
if (oldBeanDefinition != null) {
if (!this.allowBeanDefinitionOverriding) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
"': There is already [" + oldBeanDefinition + "] bound.");
}
else {
if (this.logger.isInfoEnabled()) {
this.logger.info("Overriding bean definition for bean '" + beanName +
"': replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
}
}
}
else {
this.beanDefinitionNames.add(beanName);
this.frozenBeanDefinitionNames = null;
}
this.beanDefinitionMap.put(beanName, beanDefinition);
resetBeanDefinition(beanName);
}
}
推荐阅读
-
Spring IOC源码-bean加载 博客分类: spring springiocbean加载
-
Spring IOC 源码-bean解析 博客分类: spring springioc源码
-
Spring学习(二)---在IoC容器中装配Bean 博客分类: Spring 3.x 企业应用开发笔记 springbeanioc框架
-
Spring IoC浅析 博客分类: Spring Spring容器IoCAOP源码
-
Spring的IOC源码解读&UML 博客分类: javaspringiocbean javaspringiocbean
-
Spring的IoC容器实现原理(一)#loadBeanDefinition 博客分类: Spring SpringIoC
-
String之PropertyPlaceholderConfigurery源码解析 博客分类: spring PropertyPlaceholderConfigurery源码详解使用
-
Spring结构大概 博客分类: 源码 springBeanFactorygetBean
-
二、Spring源码分析——BeanFactory 博客分类: Spring Spring源码分析BeanFactory
-
(转)Spring思维导图,让Spring不再难懂(ioc篇) 博客分类: Spring SpringIOC思维导图