从最简单的XmlBeanFactory开始读Spring源码(核

2022-12-05  本文已影响0人  王侦

示例程序:

public class BeanFactoryTest {
    @SuppressWarnings(value={"deprecation"})
    public static void main(String[] args) {
        BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("spring-bf.xml"));
        Object a = beanFactory.getBean("componentA");
        Object b = beanFactory.getBean("componentB");
        System.out.println(a);
        System.out.println(b);
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="componentA" class="com.wz.spring.xml.ComponentA"/>
    <bean id="componentB" class="com.wz.spring.xml.ComponentB"/>
</beans>

1.核心流程

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

这里reader是:

private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);

实际加载BeanDefinition是在:

doLoadBeanDefinitions(inputSource, encodedResource.getResource());

这里核心流程就两步:

    protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
            throws BeanDefinitionStoreException {

        try {
            Document doc = doLoadDocument(inputSource, resource);
            int count = registerBeanDefinitions(doc, resource);
            if (logger.isDebugEnabled()) {
                logger.debug("Loaded " + count + " bean definitions from " + resource);
            }
            return count;
        }

2.BeanDefinitionDocumentReader解析并注册BeanDefinition

核心是BeanDefinitionDocumentReader,会在DefaultBeanDefinitionDocumentReader#doRegisterBeanDefinitions进行解析处理。

    protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
        // 条件成立:说明root是spring命名空间
        if (delegate.isDefaultNamespace(root)) {
            // <beans>
            //     <bean> ... </bean>
            //     <bean> ... </bean>
            // </beans>
            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;
                    // 子标签也是spring默认标签
                    if (delegate.isDefaultNamespace(ele)) {
                        parseDefaultElement(ele, delegate);
                    }
                    else {
                        delegate.parseCustomElement(ele);
                    }
                }
            }
        }
        else {
            // 解析自定义标签
            delegate.parseCustomElement(root);
        }
    }
    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);
        }
    }

import标签示例:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.Springframework.org/schema/beans"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
            <import resource="application-business1.xml"/>
            <import resource="application-business2.xml"/>
            <import resource="application-business3.xml"/>
            ...
</beans>

alias标签示例:

<bean id="testBean" class="xx.xx.xx.xxBean"/>
1.要给这个JavaBean增加别名,以方便使用时,我们可以直接使用bean标签中的name属性:
<bean id="testBean" name="testBean,testBean2" class="xx.xx.xx.xxBean"/>
2.Spring还提供了 另外一种声明别名的方式:
<bean id="testBean" class="xx.xx.xx.xxBean"/>
<alias name="testBean" alias="testBean,testBean2"/>

处理bean标签:

    protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
        // 这里处理了bean名字以及解析AbstractBeanDefinition
        BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
        if (bdHolder != null) {
            // 这里进行装饰,主要处理自定义属性
            bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
            try {
                // Register the final decorated instance.
                // 将bd注册到容器里面
                BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
            }
            catch (BeanDefinitionStoreException ex) {
                getReaderContext().error("Failed to register bean definition with name '" +
                        bdHolder.getBeanName() + "'", ele, ex);
            }
            // Send registration event.
            // 发布注册完成事件
            getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
        }
    }

BeanDefinitionParserDelegate#parseBeanDefinitionElement的方法:

注意别名的注册,是放在aliasMap中ConcurrentHashMap,key - alias,value - beanName。

核心在重载方法BeanDefinitionParserDelegate#parseBeanDefinitionElement()处理BeanDefinition:

    public AbstractBeanDefinition parseBeanDefinitionElement(
            Element ele, String beanName, @Nullable BeanDefinition containingBean) {

        this.parseState.push(new BeanEntry(beanName));

        String className = null;
        // 读取bean标签的className,除非从parent标签继承
        if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
            className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
        }
        String parent = null;
        // parent标签
        if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
            parent = ele.getAttribute(PARENT_ATTRIBUTE);
        }

        try {
            // 创建bd对象,设置beanClass或者beanClassName
            AbstractBeanDefinition bd = createBeanDefinition(className, parent);

            // 解析attribute信息:scope、lazy-init、init-method、depends-on等
            parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
            // description
            bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));

            // meta
            parseMetaElements(ele, bd);
            // lookup-method
            parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
            // replaced-method
            parseReplacedMethodSubElements(ele, bd.getMethodOverrides());

            // 解析constructor-arg子元素
            parseConstructorArgElements(ele, bd);
            // 解析property子元素
            parsePropertyElements(ele, bd);
            // 解析qualifier子元素
            parseQualifierElements(ele, bd);

            bd.setResource(this.readerContext.getResource());
            bd.setSource(extractSource(ele));

            return bd;
        }

注意property或者constructor-arg解析时:

正好对应Bean的xml配置:

<bean id="xxxComponent" name="xxxComponent" class="xx.xx.xx.xxxComponent">
    <meta key="meta_1" value="meta_val_1"/>
    <meta key="meta_2" value="meta_val_2"/>
    ...
    
    <property name="key1" value="value1"/>
    <property name="key2" value="value2"/>
    ...
    
    
    <constructor-arg index="0">
        <value>aaa</value>
    </constructor-arg>
    <constructor-arg index="1">
        <value>bbb</value>
    </constructor-arg>
    <constructor-arg index="2">
        <map>
            <entry key="key" value="value">
            ...
        </map>
    </constructor-arg>
    
</bean>

重点来看看BeanDefinitionParserDelegate#parseBeanDefinitionAttributes

    public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName,
            @Nullable BeanDefinition containingBean, AbstractBeanDefinition bd) {

        // scope属性的处理
        if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
            error("Old 1.x 'singleton' attribute in use - upgrade to 'scope' declaration", ele);
        }
        else if (ele.hasAttribute(SCOPE_ATTRIBUTE)) {
            bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));
        }
        else if (containingBean != null) {
            // Take default from containing bean in case of an inner bean definition.
            bd.setScope(containingBean.getScope());
        }

        // abstract为true,表示是一个抽象bean,只能让子bean去继承
        if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) {
            bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE)));
        }

        // lazy-init
        String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
        if (isDefaultValue(lazyInit)) {
            lazyInit = this.defaults.getLazyInit();
        }
        bd.setLazyInit(TRUE_VALUE.equals(lazyInit));

        // autowire值
        String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);
        bd.setAutowireMode(getAutowireMode(autowire));

        // depends-on
        if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {
            String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);
            bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, MULTI_VALUE_ATTRIBUTE_DELIMITERS));
        }

        // autowire-candidate设置为false后,当前bean不能参与其余bean的自动依赖注入。默认是true。
        String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE);
        if (isDefaultValue(autowireCandidate)) {
            String candidatePattern = this.defaults.getAutowireCandidates();
            if (candidatePattern != null) {
                String[] patterns = StringUtils.commaDelimitedListToStringArray(candidatePattern);
                bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns, beanName));
            }
        }
        else {
            bd.setAutowireCandidate(TRUE_VALUE.equals(autowireCandidate));
        }

        // primary,依赖注入有多个候选对象,选择primary
        if (ele.hasAttribute(PRIMARY_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);
            bd.setInitMethodName(initMethodName);
        }
        else if (this.defaults.getInitMethod() != null) {
            bd.setInitMethodName(this.defaults.getInitMethod());
            bd.setEnforceInitMethod(false);
        }

        // destroy-method
        if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE)) {
            String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE);
            bd.setDestroyMethodName(destroyMethodName);
        }
        else if (this.defaults.getDestroyMethod() != null) {
            bd.setDestroyMethodName(this.defaults.getDestroyMethod());
            bd.setEnforceDestroyMethod(false);
        }

        // factory-method
        if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) {
            bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE));
        }
        // factory-bean
        if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) {
            bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE));
        }

        return bd;
    }

3.继承体系


4.Spring IOC容器架构图

上一篇 下一篇

猜你喜欢

热点阅读