spring源码之bean包

测试代码如下:

创建一个Teacher类:

public class Teacher {

    private String description = "teacher";

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

在包下创建一个spring.xml

在<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
<bean id="teacher" class="com.cosmos.spring.Teacher"/>

</beans>

测试代码:

@SuppressWarnings("deprecation")
public class BeanFactoryTest {

   @Test
    public void testSimpleLoad() {
    	/**
    	*XmlBeanFactory已经被弃用,此处是为了测试bean
    	/
        //ApplicationContext ap = new ClassPathXmlApplicationContext("com/cosmos/spring/spring.xml");
         BeanFactory bf = new XmlBeanFactory(new ClassPathResource("com/cosmos/spring/spring.xml"));
        Teacher bean = (Teacher) ap.getBean("teacher");
        System.out.println(bean.getDescription());
    }

}

输出:
spring源码之bean包

以上是一个很简单的spring的bean托管案例。那么他是怎么实现的呢?以下是spring加载的顺序
spring源码之bean包

第一步:通过ClassPathResource将目录下的xml文件转换为程序可识别的Resource(resource的具体介绍可参考上一篇博文)
第二步:通过XmlBeanFactory类的构造函数调用

public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
		super(parentBeanFactory);
		this.reader.loadBeanDefinitions(resource);
	}

执行XmlBeanDefinitionReader的loadBeanDefinitions()方法来解析配置文件并生成bean。

第三步:解析+注册(以下代码省略部分异常捕获)

doLoadBeanDefinitions():

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) {
			/**
			 此方法做了两件事:
			 1.获取对xml文件的验证模式
			 2.加载xml文件,并得到对应的document
			 */
			Document doc = doLoadDocument(inputSource, resource);
			//根据返回的document注册bean的信息
			int count = registerBeanDefinitions(doc, resource);
			if (logger.isDebugEnabled()) {
				logger.debug("Loaded " + count + " bean definitions from " + resource);
			}
			return count;

	}

doLoadDocument():

	此方法的实现类为:DefaultDocumentLoader
	使用的SAX解析
	@Override
	public Document loadDocument(InputSource inputSource, EntityResolver entityResolver,
			ErrorHandler errorHandler, int validationMode, boolean namespaceAware) throws Exception {

		DocumentBuilderFactory factory = createDocumentBuilderFactory(validationMode, namespaceAware);
		if (logger.isTraceEnabled()) {
			logger.trace("Using JAXP provider [" + factory.getClass().getName() + "]");
		}
		DocumentBuilder builder = createDocumentBuilder(factory, entityResolver, errorHandler);
		return builder.parse(inputSource);
	}

registerBeanDefinitions():记录本次加载次数

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
		//使用DefalutBeanDefinitionDocumentReader实例化BeanDefinitionDocumentReader
		BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
		/**
		 * 在实例化BeanDefinitionDocumentReader的时候会将BeanDefinitionRegistry传入,默认使用
		 * 继承自己DefalutListableBeanFactory的子类
		 * countBefore:记录统计前BeanDefinition的加载个数
		 */
		int countBefore = getRegistry().getBeanDefinitionCount();
		//加载及注册bean
		documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
		//记录本次加载的BeanDefinition个数
		return getRegistry().getBeanDefinitionCount() - countBefore;
	}

registerBeanDefinitions():主要用来调用doRegisterBeanDefinitions

doRegisterBeanDefinitions():核心处理类

	@SuppressWarnings("deprecation")  // for Environment.acceptsProfiles(String...)
	protected void doRegisterBeanDefinitions(Element root) {
		//解析处理类
		BeanDefinitionParserDelegate parent = this.delegate;
		this.delegate = createDelegate(getReaderContext(), root, parent);
		
		//此处用来区别不同的生产环境,类似dev之类的,
		if (this.delegate.isDefaultNamespace(root)) {
			//处理profile属性
			String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
			if (StringUtils.hasText(profileSpec)) {
				String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
						profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
				// We cannot use Profiles.of(...) since profile expressions are not supported
				// in XML config. See SPR-12458 for details.
				if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
					if (logger.isDebugEnabled()) {
						logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec +
								"] not matching: " + getReaderContext().getResource());
					}
					return;
				}
			}
		}
		//解析前处理(模板方法),使用者可重写此方法,来实现解析前记录部分信息
		preProcessXml(root);
		//解析方法
		parseBeanDefinitions(root, this.delegate);
		//解析后处理
		postProcessXml(root);
		this.delegate = parent;
	}

parseBeanDefinitions(root, this.delegate) :此方法用来解析beans,bean并分别处理

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
		//对beans的处理
		if (delegate.isDefaultNamespace(root)) {
			NodeList nl = root.getChildNodes();
			for (int i = 0; i < nl.getLength(); i++) {
				Node node = nl.item(i);
				if (node instanceof Element) {
					Element ele = (Element) node;
					if (delegate.isDefaultNamespace(ele)) {
						//对bean的处理
						parseDefaultElement(ele, delegate);
					}
					else {
						//对bean的处理(自定义标签)
						delegate.parseCustomElement(ele);
					}
				}
			}
		}
		else {
			delegate.parseCustomElement(root);
		}
	}

parseDefaultElement(ele, delegate):处理主标签

private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
		//import标签的处理
		if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
			importBeanDefinitionResource(ele);
		}
		//alias标签的处理
		else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
			processAliasRegistration(ele);
	}
		//对bean标签的处理
		else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
			processBeanDefinition(ele, delegate);
		}
		//对beans标签的处理
		else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
			// recurse
			doRegisterBeanDefinitions(ele);
		}
	}

以下先介绍Bean的具体解析及注册:

processBeanDefinition(ele, delegate)

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
		//元素解析,bdHolder中包含配置文件中的各种属性,包括class,name,id,alias等等
		BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
		if (bdHolder != null) {
			//自定义标签库
			bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
			try {
				// Register the final decorated instance.
				//注册bdHolder
				BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
			}
			catch (BeanDefinitionStoreException ex) {
				getReaderContext().error("Failed to register bean definition with name '" +
						bdHolder.getBeanName() + "'", ele, ex);
			}
			// Send registration event.
			//通知相关的监听器,这个bean已经加载成功(用户可自定义监听器)
			getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
		}
	}

BeanDefinitionHolder()

public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
//解析id属性
String id = ele.getAttribute(ID_ATTRIBUTE);
//解析name属性
String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);

    //分割name属性
    List<String> aliases = new ArrayList<>();
    if (StringUtils.hasLength(nameAttr)) {
        String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
        aliases.addAll(Arrays.asList(nameArr));
    }

    String beanName = id;
    if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
        beanName = aliases.remove(0);
        if (logger.isTraceEnabled()) {
            logger.trace("No XML 'id' specified - using '" + beanName
                    + "' as bean name and " + aliases + " as aliases");
        }
    }

    if (containingBean == null) {
        checkNameUniqueness(beanName, aliases, ele);
    }
	//解析获取bean的属性,包括parent,property等子元素
    AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
    if (beanDefinition != null) {
        if (!StringUtils.hasText(beanName)) {
            try {
                //如果不存在beanName,就根据spring提供的命名规则为当前bean生成对应的beanName
                if (containingBean != null) {
                    //自定义benaName生成规则
                    beanName = BeanDefinitionReaderUtils.generateBeanName(
                            beanDefinition, this.readerContext.getRegistry(), true);
                } else {
                    beanName = this.readerContext.generateBeanName(beanDefinition);
                    // Register an alias for the plain bean class name, if still possible,
                    // if the generator returned the class name plus a suffix.
                    // This is expected for Spring 1.2/2.0 backwards compatibility.
                    String beanClassName = beanDefinition.getBeanClassName();
                    if (beanClassName != null
                            && beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length()
                            && !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
                        aliases.add(beanClassName);
                    }
                }
                if (logger.isTraceEnabled()) {
                    logger.trace("Neither XML 'id' nor 'name' specified - "
                            + "using generated bean name [" + beanName + "]");
                }
            } catch (Exception ex) {
                error(ex.getMessage(), ele);
                return null;
            }
        }
        String[] aliasesArray = StringUtils.toStringArray(aliases);
        return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
    }

    return null;
}

最后,解析和装饰都已经完成,该注册了。
让我们回到processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate)这个方法
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder,getReaderContext().getRegistry());进行注册。
对于bean的注册,我们可以理解为spring将解析出来的beanDefinition放入map集合之中,不过除此之类,spring还做了大量的验证以及高并发处理。代码如下

public static void registerBeanDefinition(
			BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
			throws BeanDefinitionStoreException {

		// Register bean definition under primary name.
		String beanName = definitionHolder.getBeanName();
		//注册bean(DefaultListableBeanFactory)
		registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

		// Register aliases for bean name, if any.
		//注册所有别名
		String[] aliases = definitionHolder.getAliases();
		if (aliases != null) {
			for (String alias : aliases) {
				registry.registerAlias(beanName, alias);
			}
		}
	}
	@Override
	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 {
				/**
				 *
				 * 注册前的最后一次校验,不同于xml文件校验
				 * 主要是对于AbstractBeanDefinition属性的methodOverrides校验
				 * 校验methodOverrides是否与工厂方法并存或者methodOverrides对应的方法根本不存在
				 */
				((AbstractBeanDefinition) beanDefinition).validate();
			}
			catch (BeanDefinitionValidationException ex) {
				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
						"Validation of bean definition failed", ex);
			}
		}

		BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
		if (existingDefinition != null) {
			if (!isAllowBeanDefinitionOverriding()) {
				//如果对应的beanName已经注册并且在配置了bean不允许被覆盖,则抛出异常
				throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
			}
			else if (existingDefinition.getRole() < beanDefinition.getRole()) {
				// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
				if (logger.isInfoEnabled()) {
					logger.info("Overriding user-defined bean definition for bean '" + beanName +
							"' with a framework-generated bean definition: replacing [" +
							existingDefinition + "] with [" + beanDefinition + "]");
				}
			}
			else if (!beanDefinition.equals(existingDefinition)) {
				if (logger.isDebugEnabled()) {
					logger.debug("Overriding bean definition for bean '" + beanName +
							"' with a different definition: replacing [" + existingDefinition +
							"] with [" + beanDefinition + "]");
				}
			}
			else {
				if (logger.isTraceEnabled()) {
					logger.trace("Overriding bean definition for bean '" + beanName +
							"' with an equivalent definition: replacing [" + existingDefinition +
							"] with [" + beanDefinition + "]");
				}
			}
			this.beanDefinitionMap.put(beanName, beanDefinition);
		}
		else {
			if (hasBeanCreationStarted()) {
				// Cannot modify startup-time collection elements anymore (for stable iteration)
				//因为beanDefinitionMap是全局变量,这里定会存在并发访问的情况
				synchronized (this.beanDefinitionMap) {
					//注册beanName
					this.beanDefinitionMap.put(beanName, beanDefinition);
					List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
					updatedDefinitions.addAll(this.beanDefinitionNames);
					updatedDefinitions.add(beanName);
					this.beanDefinitionNames = updatedDefinitions;
					if (this.manualSingletonNames.contains(beanName)) {
						Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
						updatedSingletons.remove(beanName);
						this.manualSingletonNames = updatedSingletons;
					}
				}
			}
			else {
				// Still in startup registration phase
				this.beanDefinitionMap.put(beanName, beanDefinition);
				//记录beanName
				this.beanDefinitionNames.add(beanName);
				this.manualSingletonNames.remove(beanName);
			}
			this.frozenBeanDefinitionNames = null;
		}

		if (existingDefinition != null || containsSingleton(beanName)) {
			//重置所有beanName对应的缓存
			resetBeanDefinition(beanName);
		}
	}

至此,spring的解析与注册结束了。