(1)首先委托BeanDefinitionDelegate类的parseBeanDefinitionElement方法进行元素解析,返回BeanDefinitionHolder类型的实例dbHolder,经过这个方法后,dbHolder实例已经包含我们配置文件中配置的各种属性了,例如class,name,id,alias之类的属性.
(2)当返回的dbHolder不为空的情况下若存在默认标签的子节点下再有自定义属性,还需要再次对自定义标签进行解析.
(3)解析完成之后,需要对解析后的dbHolder进行注册,同样,注册操作委托给了BeanDefinitionReaderUtils的registerBeanDefinition方法.
(4)最后发出响应时间,通知相关的监听器,这个bean已经加载完成了.
(1)如果name属性值不为空,就以逗号来分割它,并存放在ArrayList中.
如果有id就把id作为beanName,否则就把aliases数组的第一个元素作为beanName,如果还为空就使用内部规则生成一个beanName(类名#0,1,2,3…)
(2)对自定义标签的解析的过程如下:
public AbstractBeanDefinition parseBeanDefinitionElement(Element ele, String beanName, BeanDefinition containingBean){
this.parseState.push(new BeanEntry(beanName));
String className = null;
// 解析class属性
if (ele.hasAttribute(CLASS_ATTRIBUTE)){
className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
}
try {
String parent = null;
//解析parent属性
if (ele.hasAttribute(PARENT_ATTRIBUTE)){
parent = ele.getAttribute(PARENT_ATTRIBUTE);
}
//1.创建用于承载属性的AbstractBeanDefinition类型的GenericBeanDefinition
AbstractBeanDefinition bd = createBeanDefinition(className, parent);
//2.硬编码解析默认bean的各种属性
parseBeanDefinitionAttribute(ele, beanName, containingBean, db);
//3.解析元数据
parseMetaElements(ele, bd);
//4.解析lookup-method属性
parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
//5.解析replaced-method属性
parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
//6.解析构造函数参数
parseConstructorArgElements(ele, bd);
//7.解析property子元素
parsePropertyElements(ele, bd);
//8解析qualifier子元素
parseQualifierElements(ele, bd);
bd.setResource(this, readerContext.getResource());
bd.setSource(extractSource(ele));
return bd;
}
}
1. 创建用于属性继承的BeanDefinition
BeanDefinition是一个接口,在spring中存在三种实现:RootBeanDefinition, ChildBeanDefinition, 以及GenericBeanDefinition.
三种实现都继承了AbstractBeanDefinition,其中BeanDefinition是配置文件元素标签在容器中的内部表示形式.
标签拥有class,scope,lazy-init等配置属性,BeanDefinition则提供了相应的beanClass, scope, lazyInit属性,BeanDefinition和中的属性是一一对应的.
在配置文件中可以定义父和子,父用RootBeanDefinition表示,而子用ChildBeanDefinition表示,而没有父的子就使用RootBeanDefinition表示.AbstractBeanDefinition对两者共同的类信息进行抽象.
Spring通过BeanDefinition将配置文件中的配置信息转换为容器的内部表示,并将这些BeanDefinition注册到BeanDefinitionRegistry中.Spring容器的BeanDefinitionRegistry就像是Spring配置信息的内存数据库,主要是以map的形式保存,后续操作直接从BeanDefinitionRegistry中读取配置信息.
BeanDefinition在被创建的时候是如何实现实例的唯一性的:
BeanDefinitionReaderUtils.java
public static AbstractBeanDefinition createBeanDefinition(String parentName,String className, ClassLoader classLoader) throws ClassNotFoundException{
GenericBeanDefinition db = new GenericBeanDefinition();
//parentName 可能为空
bd.setParentName(parentName);
if (className != null){
if (classLoader != null){
//如果classLoader不为空,则使用和传入的classLoader同一虚拟机加载类对象,否则只是记录className
bd.setBeanClass(ClassUtils.forName(className, classLoader));
}else{
bd.setBeanClassName(className);
}
}
return bd;
}
2. 解析Bean元素的各种属性
创建完BeanDefinition属性之后,就需要对bean元素的各种属性进行解析了.
public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName, BeanDefinition containingBean, AbstractBeanDefinition bd){
//解析scope属性
if (ele.hasAttribute(SCOPE_ATTRIBUTE)){
//Spring 2.x "scope" attribute
bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));
if (ele.hasAttribute(SINGLETON_ATTRIBUTE)){
//scope 与singleton两个属性只能指定其中之一,不可以同时出现,否则Spring将会报异常
error("Specify either 'scope' or 'singleton', not both", ele);
}
}
//解析singleton属性
else if (ele.hasAttribute(SINGLETON_ATTRIBUTE)){
// Spring 1.x "singleton" attribute
bd.setScope(TRUE_VAULE.equals(ele.getAttribute(SINGLETON_ATTRIBUTE))?BeanDefinition.SCOPE_SINGLETON : BeanDefintion.SCOPE_PROTOTYPES);
}
else if (containingBean != null){
// Take default from containing bean in case of inner bean definition
// 在嵌入beanDefinition情况下且没有单独指定scope属性则使用父类默认的属性
bd.setScope(containingBean.getScope());
}
//解析abstract属性
if(ele.hasAttribute(ABSTRACT_ATTRIBUTE)){
bd.setAbstract(TRUE_VALUE.equels(ele.getAttribute(ABSTRACT_ATTRIBUTE)));
}
//解析lazy-init属性
String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
if (DEFAULT_VALUE.quals(lazyInit)){
lazyInit = this.defaults.getLazyInit();
}
//若没有设置或设置成其他字符都会被设置为false
bd.setLazyInit(TRUE_VALEU.equals(lazyInit);
//解析autowire属性
String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);
bd.setAutowireMode(getAutowireMode(autowire));
//解析dependency-check属性
String dependencyCheck = ele.getAttribute(DEPENDENCY_CHECK_ATTRIBUTE);
bd.setDependencyCheck(getDependencyCheck(dependencyCheck));
//解析depends-on属性
if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)){
String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);
bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, NULTI_VALUE_ATTRIBUTE_DELIMITERS));
}
//解析autowire-candidate属性
String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE);
if ("".equals(autowireCandidate)|| DEFAULT_VALUE.equals(autowireCandidate)){
String candidatePattern = this.default.getAutowireCandates();
if (candidatePattern != null){
String[] patterns = StringUtils.commaDelimitedListToStringArray(candidatePattern);
bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns, beanName));
}
}
else {
bd.setAutowireCandidate(TRUE_VALUE.equals(autowireCandidate));
}
//解析private属性
if (ele.hasAttribute(PRIVATE_ATTRIBUTE)){
bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE)));
}
//解析init_method属性
if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)){
String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE);
if (!"".equals(initMethodName)){
bd.setInitMethodName(initMethodName);
}
}
else {
if (this.defaults.getInitMethod()!=null){
bd.setInitMethodName(this.defaults.getInitMethos());
bd.setEnforceInitMethod(false);
}
}
//解析destroy-methos属性
if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE)){
String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE);
if (!"".equals(destroyMethodName)){
bd.setDestroyMethodName(destroyMethodName);
}
}
else{
if (this.default.getDestroyMethod() != null){
bd.setDstroyMethosName(this.default.getDestoryMethod);
bd.setEnforceDestroyMethod(false);
}
}
//解析factory-method解析
if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)){
bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE));
}
return bd;
}
3.解析子元素meta
<bean id ="myTestBean" class="bean.MyTestBean">
<meta key="testStr" value="aaaaa">
</bean>
## mate元素的解析代码
public void parseMetaElements(Element ele, BeanMetadataAttributeAccessor attributeAccessor){
//获取当前节点的所有子元素
NodeList nl = ele.getChildNodes();
for (int i =0; i < nl.getLength(); i++){
Node node = nl.item(i);
//提取meta
if (isCandidateElement(node) && nodeNameEquals(node, META_ELEMENT)){
Element metaElement = (Element)node;
String key = metaElement.getAttribute(KET_ATTRIBUTE);
String value = metaElement.getAttribute(VALUE_ATTRIBUTE);
//使用key, value构造BeanMetadataAttribute
BeanMetadataAttribute attribute = new BeanMetadataAttribute(key, value);
attribute.setSource(extractSource(metaElement));
//记录信息
attributeAccessor.addMetadataAttribute(attribute);
}
}
}
还有其他子元素的解析,这里就不细说了