Spring源码深度解析(郝佳)-学习-源码解析-factory-method

20 篇文章 1 订阅
18 篇文章 0 订阅

本文要解析的是Spring factory-method是如何来实现的,话不多说,示例先上来。

Stu.java

public class Stu {
    public String stuId;
    public Stu(String stuId) {
        this.stuId = stuId;
    }
}

StuFactory.java

public class StuFactory {
    //动态创建类
    public Stu getDynamicStu(String stuId) {
        return new Stu(stuId);
    }
}

spring50.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--生成对象的工厂-->
    <bean id="stuFactory" class="com.spring_1_100.test_41_50.test50.StuFactory"/>

    <!--动态获取对象-->
    <bean id="dynamicStu" factory-bean="stuFactory" factory-method="getDynamicStu">
        <!--传入getDynamicStu方法的参数-->
        <constructor-arg value="11"/>
    </bean>
</beans>

Test50.java

public class Test50 {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:spring_1_100/config_41_50/spring50.xml");
        //获取动态Bean
        Stu stu =(Stu) ac.getBean("dynamicStu");
        System.out.println(JSON.toJSONString(stu));
    }
}

【输出结果】
{“stuId”:“11”}

首先,我们关于dynamicStu bean的解析。

BeanDefinitionParserDelegate.java

/**
 * 1.首先委托BeanDefinitionDelegate类的parseBeanDefinitionElement方法进行元素解析,返回BeanDefinitionHolder类型的bdHolder
 *   ,经过这个方法后bdHolder实例己经包含我们配置文件中配置的各个属性了,例如class,name,id,alias之类的属性
 * 2.当返回的bdHolder不为空的情况下若存在默认标签的子节点下再有自定义属性,还需要再次对自定义的属性进行标签解析
 * 3.解析完成后,需要对解析后的bdHolder进行注册,更新,注册操作委托给了BeanDefinitionReaderUtils的registerBeanDefinition方法
 * 4.最后发出响应事件,通知相关的监听器,这个bean己经加载好了
 */
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
	BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
	// BeanDefinitionHolder是对BeanDefinition的封装,即Bean定义封装类
	// 对文档中的元素解析由BeanDefinitionParserDelegate实现
	// BeanDefinitionHolder bdHolder = deletate.parseBeanDefinitionElement(element)
	// BeanDefinitionHolder是对
	if (bdHolder != null) {
		/***
		 * 如果需要的话就对 beanDefinition 进行装饰,那么这句代码的作用就是什么功能呢?
		 * 这句代码的使用场景如下:
		 * <bean id="test" class="test.MyClass">
		 *     <mybean:user username="aaaa"/>
		 * </bean>
		 * 当 Spring 中的 bean 使用了默认的标签配置,但是其中的子元素却使用了自定义的配置,这句代码就起作用了,可能会有人会疑问,
		 * 之前讲过,对 bean 的解析分成两种类型,一种是默认的类型解析,另一种是自定义类型解析,这不正是自定义类型解析吗?为什么会在
		 * 默认的类型解析中单独的添加一个方法的处理呢,确实,这个问题很让人迷惑,但是,不知道聪明的读者有没有发现,这个自定义类型并不是
		 * 以 Bean 的形式出现的呢?我们之前讲过两种类型的不同处理只是针对 bean 的,这里我们看到,这个自定义类型其实是属性,好了,我们
		 * 我们继续分析这个代码
		 */
		bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
		try {
			// 向Spring Ioc容器注册解析得到的bean定义,这是Bean定义向Ioc容器注册的入口
			BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
		}
		catch (BeanDefinitionStoreException ex) {
			getReaderContext().error("Failed to register bean definition with name '" +
					bdHolder.getBeanName() + "'", ele, ex);
		}

		// 在完成向Spring IoC容器注册解析得到的Bean定义之后,发送注册事件
		getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
	}
}

BeanDefinitionParserDelegate.java

/**
 * 解析bean元素的入口
 */
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
    return parseBeanDefinitionElement(ele, null);
}

BeanDefinitionParserDelegate.java

/**
 * 解析Bean配置信息中的元素,这个方法中主要处理的元素的id,name,别名属性
 */
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
    // 获取元素中的id属性值
    String id = ele.getAttribute(ID_ATTRIBUTE);
    // 获取元素的name属性值
    String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
    // 获取bean元素的alias属性值
    List<String> aliases = new ArrayList();
    // 将元素的中的所有alias属性值放入到别名中
    if (StringUtils.hasLength(nameAttr)) {
        String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
        aliases.addAll(Arrays.asList(nameArr));
    }
    String beanName = id;
    // 如果元素中没有配置id属性,将别名中的第一个值赋值给beanName
    if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
        beanName = aliases.remove(0);
        if (logger.isDebugEnabled()) {
            logger.debug("No XML 'id' specified - using '" + beanName +
                    "' as bean name and " + aliases + " as aliases");
        }
    }
    // 检查元素所配置的id或者name唯一性
    if (containingBean == null) {
        //检查元素的所配置的id,name或者别名是否重复
        checkNameUniqueness(beanName, aliases, ele);
    }
    // 详细对元素中的配置的bean定义进行解析
    AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
    if (beanDefinition != null) {
        if (!StringUtils.hasText(beanName)) {
            try {
                if (containingBean != null) {
                    // 如果元素中没有配置id,别名或者name,且没有包含子元素
                    // 元素,则解析的Bean生成一个唯一的beanName并注册
                    beanName = BeanDefinitionReaderUtils.generateBeanName(
                            beanDefinition, this.readerContext.getRegistry(), true);
                } else {
                    // 如果元素没有配置id,别名或者name,且包含子元素
                    // <bean>元素,则将解析的Bean生成一个唯一的BeanName并注册
                    beanName = this.readerContext.generateBeanName(beanDefinition);
                    String beanClassName = beanDefinition.getBeanClassName();
                    // 为解析的Bean使用别名注册时,为了向后兼容
                    // Spring 1.2 /2.0 给别名添加后缀
                    if (beanClassName != null &&
                            beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
                            !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
                        aliases.add(beanClassName);
                    }
                }
                if (logger.isDebugEnabled()) {
                    logger.debug("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);
    }
    // 当解析出错时,返回null
    return null;
}

BeanDefinitionParserDelegate.java

 /**
 * 详细对元素中配置的Bean定义的其他的属性进行解析
 * 由于上面的方法已经对Bean的id,name和别名属性进行了处理
 * 该方法主要是处理除了这三个以外的其他的属性
 * 【注意】在解析元素的过程中没有创建和实例化对象,只是创建了Bean元素的定义类BeanDefinition,将元素中的信息
 * 设置到了BeanDefinition中作为记录,当依赖注入时才使用这些记录信息创建和实例化具体的Bean对象
 * 在对一些配置(如meta,qualifier等)的解析,我们在Spring中使用得不多,在使用Spring元素时,配置最多的就是子元素
 */
public AbstractBeanDefinition parseBeanDefinitionElement(
        Element ele, String beanName, BeanDefinition containingBean) {
    // 记录解析元素
    this.parseState.push(new BeanEntry(beanName));
    // 这里只读取元素中配置的class名字,然后载入BeanDefinition中
    // 只是记录配置的class名字,不做实例化,对象的实例化在依赖注入的时候完成
    String className = null;
    if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
        className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
    }
    try {
        String parent = null;
        // 如果<bean>元素中配置了parent属性,则获取 parent属性的值
        if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
            parent = ele.getAttribute(PARENT_ATTRIBUTE);
        }
        // 根据<bean>元素配置的class名称和parent属性值创建BeanDefinition
        // 为载入的Bean定义信息做准备
        AbstractBeanDefinition bd = createBeanDefinition(className, parent);
        // 对当前的<bean>元素中配置的一些属性进行解析和设置,如果配置了单态(singleton)属性等
        parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
        // 为<bean>元素解析的Bean设备描述信息
        bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
        // 为<bean>元素的meta(元信息进行解析)
        parseMetaElements(ele, bd);
        // 为<bean>元素的lookup-Method属性进行解析
        parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
        // 为<bean>元素的replaced-Method属性进行解析
        parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
        //解析<bean>元素构造方法设置
        parseConstructorArgElements(ele, bd);
        //解析<bean>元素的设置
        parsePropertyElements(ele, bd);
        // 解析<bean>元素的qualifier属性
        parseQualifierElements(ele, bd);
        // 为当前的解析了Bean设置所需要的资源和依赖对象
        bd.setResource(this.readerContext.getResource());
        bd.setSource(extractSource(ele));
        return bd;
    } catch (ClassNotFoundException ex) {
        error("Bean class [" + className + "] not found", ele, ex);
    } catch (NoClassDefFoundError err) {
        error("Class that bean class [" + className + "] depends on not found", ele, err);
    } catch (Throwable ex) {
        error("Unexpected failure during bean definition parsing", ele, ex);
    } finally {
        this.parseState.pop();
    }
    // 当前解析元素出错时,返回null
    return null;
}

BeanDefinitionParserDelegate.java

public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName,
                                                            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) {
        // 在嵌入beanDefinition的情况下且没有单独指定scope的属性则使用父类默认的
        bd.setScope(containingBean.getScope());
    }
    //解析abstract属性
    if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) {
        bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE)));
    }

    // 解析lazy-init属性
    String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
    if (DEFAULT_VALUE.equals(lazyInit)) {
        lazyInit = this.defaults.getLazyInit();
    }
    //若没有设置或者设置其他的字符会被设置为false
    bd.setLazyInit(TRUE_VALUE.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, MULTI_VALUE_ATTRIBUTE_DELIMITERS));
    }
    //解析autowire-candidate属性
    String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE);
    if ("".equals(autowireCandidate) || DEFAULT_VALUE.equals(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属性
    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);
        if (!"".equals(initMethodName)) {
            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")) {
        bd.setFactoryMethodName(ele.getAttribute("factory-method"));
    }
    // 解析factory-bean属性
    if (ele.hasAttribute("factory-bean")) {
        bd.setFactoryBeanName(ele.getAttribute("factory-bean"));
    }

    return bd;
}

BeanDefinitionParserDelegate.java

/**
 * 那么让我们来看具体的XML解析过程
 */
public void parseConstructorArgElements(Element beanEle, BeanDefinition bd) {
    NodeList nl = beanEle.getChildNodes();
    for (int i = 0; i < nl.getLength(); i++) {
        Node node = nl.item(i);
        if (isCandidateElement(node) && nodeNameEquals(node, CONSTRUCTOR_ARG_ELEMENT)) {
            parseConstructorArgElement((Element) node, bd);
        }
    }
}

BeanDefinitionParserDelegate.java

/**
 * Parse a constructor-arg element.
 * 这个代码看起来复杂,但是涉及的逻辑其实并不复杂,首先是提取constructor-arg上必要的属性(index,type,name)
 * 如果配置中指定的index属性,那么操作步骤如下
 * 1.解析Constructor-arg的子元素
 * 2.使用ConstructorArgumentValues.ValueHolder类型来封装解析出来的元素
 * 3.将type,name和index属性一并封装在ConstructorArgumentValues.ValueHolder类型中并添加至当前的BeanDefinition的ConstructorArgumentValues
 * 的indexedArgumentValues属性中
 *
 * 如果没有指定index属性,那么操作步骤如下:
 * 1.解析constructor-arg的子元素
 * 2.使用ConstructorArgumentValues.ValueHolder类型来封装解析出来的元素
 * 3.将type,name和index属性一并封装在ConstructorArgumentValues.ValueHolder类型中并添加至当前的BeanDefinition的ConstructorArgumentValues
 * 的genericArgumentValues属性中
 * 可以看到,对于是否制定的index属性来讲,Spring处理流程是不同的,关键在于属性信息被保存的位置
 * 那么整个流程后,我们尝试着进一步了解解析构造函数配置中子元素的过程,进入parsePropertyValue:
 */
public void parseConstructorArgElement(Element ele, BeanDefinition bd) {
    // 提取index 属性
    String indexAttr = ele.getAttribute(INDEX_ATTRIBUTE);
    // 提取type属性
    String typeAttr = ele.getAttribute(TYPE_ATTRIBUTE);
    // 提取name属性
    String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
    if (StringUtils.hasLength(indexAttr)) {
        try {
            /**
             * 6.解析子元素constructor-arg
             *  对构造函数是是非常常用的,同时也是非常复杂的,也相信大家对构造函数的配置都不陌生 ,举个简单的例子来说
             *  ...
             *  <beans>
             *      <!--默认的情况下是按照参数的顺序注入的,当指定的index索引后就可以改变了-->
             *      <bean id="helloBean" class="com.HelloBean">
             *          <constructor-arg index = "0">
             *              <value>郝佳
             *          </constructor-arg>
             *          <constructor-arg index="1">
             *              <value>你好
             *         </constructor-arg>
             *      </bean>
             *  </beans>
             *  上面的配置是Spring构造函数配置中最佳的基础配置,实现功能就是对HelloBean自动寻找对的函数,并在初始化的时候将设置参数传入进去
             */
            int index = Integer.parseInt(indexAttr);
            if (index < 0) {
                error("'index' cannot be lower than 0", ele);
            } else {
                try {
                    this.parseState.push(new ConstructorArgumentEntry(index));
                    // 解析ele对应的属性元素
                    Object value = parsePropertyValue(ele, bd, null);
                    ConstructorArgumentValues.ValueHolder valueHolder = new ConstructorArgumentValues.ValueHolder(value);
                    if (StringUtils.hasLength(typeAttr)) {
                        valueHolder.setType(typeAttr);
                    }
                    if (StringUtils.hasLength(nameAttr)) {
                        valueHolder.setName(nameAttr);
                    }
                    valueHolder.setSource(extractSource(ele));
                    // 不允许重复指定相同的参数
                    if (bd.getConstructorArgumentValues().hasIndexedArgumentValue(index)) {
                        error("Ambiguous constructor-arg entries for index " + index, ele);
                    } else {
                        bd.getConstructorArgumentValues().addIndexedArgumentValue(index, valueHolder);
                    }
                } finally {
                    this.parseState.pop();
                }
            }
        } catch (NumberFormatException ex) {
            error("Attribute 'index' of tag 'constructor-arg' must be an integer", ele);
        }
    } else {
        // 如果没有index属性则忽略去属性,自动寻找
        /**
         <bean id="user" class="com.spring_1_100.test_41_50.test41.User">
            <constructor-arg value="2">
            <constructor-arg value="1">
         </bean>
         */
        try {
            this.parseState.push(new ConstructorArgumentEntry());
            Object value = parsePropertyValue(ele, bd, null);
            ConstructorArgumentValues.ValueHolder valueHolder = new ConstructorArgumentValues.ValueHolder(value);
            if (StringUtils.hasLength(typeAttr)) {
                valueHolder.setType(typeAttr);
            }
            if (StringUtils.hasLength(nameAttr)) {
                valueHolder.setName(nameAttr);
            }
            valueHolder.setSource(extractSource(ele));
            bd.getConstructorArgumentValues().addGenericArgumentValue(valueHolder);
        } finally {
            this.parseState.pop();
        }
    }
}

BeanDefinitionParserDelegate.java

/**
 * 解析获取元素的值
 * 通过下面的源码解析,我们了解了Spring配置文件中的元素中的子元素的相关配置,
 * 1.ref 被封装成指向依赖对象的一个引用
 * 2.value 被封装成一个字符串类型的对象
 * 3.ref 和value都是通过解析数据类型属性值.setSource(extractSource(ele));将方法的属性或者引用与引用属性关系起来
 * 最后元素的子元素通过parsePropertySubElement()方法解析,下面我们继续分析该方法的源码,了解其解析过程
 *
 * 从代码上来看,对函数的属性元素的解析,经历了以下的几个过程
 * 1.略过description或者meta
 * 2.提取constructor-arg上的ref和value属性,以便于根据规则验证正确性,其规则为在constructor-arg 上不存在以下的情况
 * 同时既有ref又有value属性
 * 存在ref属性或者value属性且又有子元素
 * 3.ref属性的处理,使用RunTimeBeanReference封装对应的ref名称,如:
 * <constructor-arg ref="a">
 *
 * </constructor-arg>
 * 4.value属性的处理,使用TypeStringValue封装,如:
 * <constructor-arg value="a">
 * 5.子元素的处理
 * <constructor-arg >
 *      <map>
 *          <entry key="key" value="value">
 *      </map>
 * </constructor-arg>
 * 而对于子元素的处理,例如,这里反映到的在构造函数中嵌入了子元素map是怎样实现的呢?parsePropertySubElement中对实现了对各种子元素的处理
 */
public Object parsePropertyValue(Element ele, BeanDefinition bd, String propertyName) {
    String elementName = (propertyName != null) ?
            " element for property '" + propertyName + "'" :
            " element";
    // 获取中的所有的子元素,只能是ref,value,list,etc中的一种类型
    NodeList nl = ele.getChildNodes();
    Element subElement = null;
    for (int i = 0; i < nl.getLength(); i++) {
        Node node = nl.item(i);
        // 子元素是description和meta属性 不做处理
        if (node instanceof Element && !nodeNameEquals(node, DESCRIPTION_ELEMENT) &&
                !nodeNameEquals(node, META_ELEMENT)) {
            if (subElement != null) {
                error(elementName + " must not contain more than one sub-element", ele);
            } else {
                // 当property元素包含子元素
                subElement = (Element) node;
            }
        }
    }
    // 解析constructor-arg 的ref 属性
    boolean hasRefAttribute = ele.hasAttribute(REF_ATTRIBUTE);
    // 解析constructor-arg 上的value属性
    boolean hasValueAttribute = ele.hasAttribute(VALUE_ATTRIBUTE);
    // 判断属性值是ref还是value,不允许既是ref 又是value
    if ((hasRefAttribute && hasValueAttribute) ||
            ((hasRefAttribute || hasValueAttribute) && subElement != null)) {
        /**
         * 在constructor-arg上不存在:
         * 1.同时既有ref属性又有value属性
         * 2.存在ref属性或者value属性且又有子元素
         */
        error(elementName +
                " is only allowed to contain either 'ref' attribute OR 'value' attribute OR sub-element", ele);
    }
    // 如果属性值是ref ,创建一个ref 的数据对象,RuntimeBeanReference,这个对象封装了ref
    if (hasRefAttribute) {
        String refName = ele.getAttribute(REF_ATTRIBUTE);
        if (!StringUtils.hasText(refName)) {
            error(elementName + " contains empty 'ref' attribute", ele);
        }
        //一个指向运行是所依赖对象的引用 ,ref属性的处理,使用RuntimeBeanReference封装对应的ref名称
        RuntimeBeanReference ref = new RuntimeBeanReference(refName);
        ref.setSource(extractSource(ele));
        return ref;
        // 如果属性值是value,创建一个value数据对象,typedStringValue,这个对象封装了value
    } else if (hasValueAttribute) {
        // 一个持有String类型的对象
        TypedStringValue valueHolder = new TypedStringValue(ele.getAttribute(VALUE_ATTRIBUTE));
        // 设置这个value的数据对象被当前对象所引用
        valueHolder.setSource(extractSource(ele));
        return valueHolder;
    } else if (subElement != null) {
        // 解析子元素
        return parsePropertySubElement(subElement, bd);
    } else {
        // 属性值既不是ref也不是value,解析出错,返回null
        error(elementName + " must specify a ref or value", ele);
        return null;
    }
}

通过上面的解析,我们得到,将factory-method属性值保存到factoryMethodName中,将factory-bean属性值保存到factoryBeanName中,将构造函数参数保存到genericArgumentValues属性中。
我们再来看看bean的创建过程

AbstractAutowireCapableBeanFactory.java

/**
 * 在CreateBeanInstance()方法中,根据指定的初始化策略,使用了简单的工厂,工厂方法或者容器的自动装配生成java实例对象,创建对象的代码如下
 * 创建Bean的实例对象
 *
 * 虽然代码中实例化的细节非常的复杂,但是存在 createBeanInstance 方法中我人还是可以清晰的看到实例化的逻辑
 * 1.如果在  如果 RootBeanDefinition 中存在 facotryMethodName 属性,或者说在配置文件中配置了 factory-method,那么 Spring
 * 会尝试使用 instantiateusingFactoryMethod(beanName,mbd,args) 方法根据 RootBeanDefinition 中的配置生成 bean 的实例
 * 2.解析构造函数并在构造函数的实例化,因为一个 bean 对应的类中可能会有多个构造函数,而每个构造函数的参数不同,Spring 在根据参数及类型去判断最终会使用哪个
 * 构造函数进行实例化,但是判断的过程是个比较消耗性能的步骤,所以采用缓存机制 ,如果已经解析过,则不需要重复解析而是直接从
 * rootBeanDefinition 中的属性 resolvedConstructorOrFactoryMethod 缓存的值去取,否则需要再次解析,并将解析的结果添加至 RootBeanDefinition
 * 中的属性 resolvedConstructorOrFactoryMethod 中
 */
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
	// Make sure bean class is actually resolved at this point.
	// 确认Bean是可实例化的,
	// 解析 class
	Class<?> beanClass = resolveBeanClass(mbd, beanName);
	// 使用工厂方法对Bean进行实例化,
	//  getModifiers  得到的就是 前面的 的修饰符 ,这个方法 字段和方法 都有。这个方法的值是 修饰符 相加的到的值。
	/**
	 * public class Test1 {
	 *
	 *     String c;
	 *     public String a;
	 *     private String b;
	 *     protected String d;
	 *     static String e;
	 *     final String f="f";
	 *
	 * }
	 *
	 *  Field[] fields = Test1.class.getDeclaredFields();
	 *         for( Field field: fields) {
	 *             System.out.println( field.getName() +":" + field.getModifiers() );
	 *         }
	 * c:0
	 * a:1
	 * b:2
	 * d:4
	 * e:8
	 * f:16
	 */
	// 所以:什么都不加 是0 , public  是1 ,private 是 2 ,protected 是 4,static 是 8 ,final 是 16。
	if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
		throw new BeanCreationException(mbd.getResourceDescription(), beanName,
				"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
	}
	// 如果工厂方法不不为空,则使用工厂方法初始化策略
	if (mbd.getFactoryMethodName() != null)  {
		// 调用工厂方法进行实例化
		return instantiateUsingFactoryMethod(beanName, mbd, args);
	}
	
	// 使用容器的自动装配方法进行实例化
	boolean resolved = false;
	boolean autowireNecessary = false;
	if (args == null) {
		synchronized (mbd.constructorArgumentLock) {
			// 一个类有多个构造函数都有不同的参数,所以调用需要根据参数锁定构造函数或者对应的工厂方法 | 一个类有多个构造函数,每个构造函数都有不同的参数,
			// 所以调用前需要先根据参数锁定构造函数或者工厂方法
			if (mbd.resolvedConstructorOrFactoryMethod != null) {
				resolved = true;
				autowireNecessary = mbd.constructorArgumentsResolved;
			}
		}
	}
	//  如果已经解析过,则使用解析好的构造函数方法不需要再次锁定
	if (resolved) {
		if (autowireNecessary) {
			// 配置了自动装配属性,使用了容器的自动装配进行实例化
			//容器的自动装配根据参数的类型匹配Bean的构造方法
			return autowireConstructor(beanName, mbd, null, null);
		}
		else {
			// 使用了默认无参构造方法进行实例化
			return instantiateBean(beanName, mbd);
		}
	}

	// Need to determine the constructor...
	// 使用了Bean的构造方法进行实例化
	Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
	if (ctors != null ||
			mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
			mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
		// 使用了容器的自动装配特性,调用匹配的构造方法进行实例化 ,构造函数自动注入 ,带参数实例化,带有参数实例化的过程相当的复杂,因为存在不确定性。
		return autowireConstructor(beanName, mbd, ctors, args);
	}

	// No special handling: simply use no-arg constructor.
	// 使用了默认的无参的构造方法进行实例化 
	return instantiateBean(beanName, mbd);
}

AbstractAutowireCapableBeanFactory.java

protected BeanWrapper instantiateUsingFactoryMethod(
		String beanName, RootBeanDefinition mbd, Object[] explicitArgs) {
	return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
}

ConstructorResolver.java

public BeanWrapper instantiateUsingFactoryMethod(
		final String beanName, final RootBeanDefinition mbd, final Object[] explicitArgs) {

	BeanWrapperImpl bw = new BeanWrapperImpl();
	this.beanFactory.initBeanWrapper(bw);

	Object factoryBean;
	Class<?> factoryClass;
	boolean isStatic;

	String factoryBeanName = mbd.getFactoryBeanName();
	if (factoryBeanName != null) {
		if (factoryBeanName.equals(beanName)) {
			throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
					"factory-bean reference points back to the same bean definition");
		}
		//获取到工厂方法factoryBean
		factoryBean = this.beanFactory.getBean(factoryBeanName);
		if (factoryBean == null) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"factory-bean '" + factoryBeanName + "' (or a BeanPostProcessor involved) returned null");
		}
		if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {
			throw new IllegalStateException("About-to-be-created singleton instance implicitly appeared " +
					"through the creation of the factory bean that its bean definition points to");
		}
		factoryClass = factoryBean.getClass();
		isStatic = false;
	}
	else {
		// It's a static factory method on the bean class.
		if (!mbd.hasBeanClass()) {
			throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
					"bean definition declares neither a bean class nor a factory-bean reference");
		}
		factoryBean = null;
		factoryClass = mbd.getBeanClass();
		isStatic = true;
	}

	Method factoryMethodToUse = null;
	ArgumentsHolder argsHolderToUse = null;
	Object[] argsToUse = null;

	if (explicitArgs != null) {
		argsToUse = explicitArgs;
	}
	else {
		Object[] argsToResolve = null;
		synchronized (mbd.constructorArgumentLock) {
			factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod;
			if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) {
				// Found a cached factory method...
				argsToUse = mbd.resolvedConstructorArguments;
				if (argsToUse == null) {
					argsToResolve = mbd.preparedConstructorArguments;
				}
			}
		}
		if (argsToResolve != null) {
			argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve);
		}
	}

	if (factoryMethodToUse == null || argsToUse == null) {
		// Need to determine the factory method...
		// Try all methods with this name to see if they match the given arguments.
		factoryClass = ClassUtils.getUserClass(factoryClass);
		//获取到所有的候选方法
		Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
		List<Method> candidateSet = new ArrayList();
		for (Method candidate : rawCandidates) {
			//取出和工厂方法名称相同的方法保存到候选方法中
			if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {
				candidateSet.add(candidate);
			}
		}
		Method[] candidates = candidateSet.toArray(new Method[candidateSet.size()]);
		AutowireUtils.sortFactoryMethods(candidates);

		ConstructorArgumentValues resolvedValues = null;
		//取出和工厂方法名称相同的方法保存到候选方法中
		boolean autowiring = (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
		int minTypeDiffWeight = Integer.MAX_VALUE;
		Set<Method> ambiguousFactoryMethods = null;

		int minNrOfArgs;
		if (explicitArgs != null) {
			minNrOfArgs = explicitArgs.length;
		}
		else {
			// We don't have arguments passed in programmatically, so we need to resolve the
			// arguments specified in the constructor arguments held in the bean definition.
			ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
			resolvedValues = new ConstructorArgumentValues();
			minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
		}

		List<Exception> causes = null;

		for (int i = 0; i < candidates.length; i++) {
			Method candidate = candidates[i];
			//获取候选方法的参数类型
			Class<?>[] paramTypes = candidate.getParameterTypes();

			if (paramTypes.length >= minNrOfArgs) {
				ArgumentsHolder argsHolder;

				if (resolvedValues != null) {
					// Resolved constructor arguments: type conversion and/or autowiring necessary.
					try {
						String[] paramNames = null;
						ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
						if (pnd != null) {
							//获取参数名  {"stuId"}
							paramNames = pnd.getParameterNames(candidate);
						}
						//创建构造函数参数持有者
						argsHolder = createArgumentArray(
								beanName, mbd, resolvedValues, bw, paramTypes, paramNames, candidate, autowiring);
					}
					catch (UnsatisfiedDependencyException ex) {
						if (this.beanFactory.logger.isTraceEnabled()) {
							this.beanFactory.logger.trace("Ignoring factory method [" + candidate +
									"] of bean '" + beanName + "': " + ex);
						}
						if (i == candidates.length - 1 && argsHolderToUse == null) {
							if (causes != null) {
								for (Exception cause : causes) {
									this.beanFactory.onSuppressedException(cause);
								}
							}
							throw ex;
						}
						else {
							// Swallow and try next overloaded factory method.
							if (causes == null) {
								causes = new LinkedList();
							}
							causes.add(ex);
							continue;
						}
					}
				}

				else {
					// Explicit arguments given -> arguments length must match exactly.
					if (paramTypes.length != explicitArgs.length) {
						continue;
					}
					argsHolder = new ArgumentsHolder(explicitArgs);
				}

				int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
						argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
				// 根据方法参数的权重匹配出最合适的方法及参数	
				if (typeDiffWeight < minTypeDiffWeight) {
					factoryMethodToUse = candidate;
					argsHolderToUse = argsHolder;
					argsToUse = argsHolder.arguments;
					minTypeDiffWeight = typeDiffWeight;
					ambiguousFactoryMethods = null;
				}
				// Find out about ambiguity: In case of the same type difference weight
				// for methods with the same number of parameters, collect such candidates
				// and eventually raise an ambiguity exception.
				// However, only perform that check in non-lenient constructor resolution mode,
				// and explicitly ignore overridden methods (with the same parameter signature).
				else if (factoryMethodToUse != null && typeDiffWeight == minTypeDiffWeight &&
						!mbd.isLenientConstructorResolution() &&
						paramTypes.length == factoryMethodToUse.getParameterTypes().length &&
						!Arrays.equals(paramTypes, factoryMethodToUse.getParameterTypes())) {
					if (ambiguousFactoryMethods == null) {
						ambiguousFactoryMethods = new LinkedHashSet();
						ambiguousFactoryMethods.add(factoryMethodToUse);
					}
					ambiguousFactoryMethods.add(candidate);
				}
			}
		}

		if (factoryMethodToUse == null) {
			List argTypes = new ArrayList(minNrOfArgs);
			if (explicitArgs != null) {
				for (Object arg : explicitArgs) {
					argTypes.add(arg != null ? arg.getClass().getSimpleName() : "null");
				}
			}
			else {
				Set valueHolders = new LinkedHashSet(resolvedValues.getArgumentCount());
				valueHolders.addAll(resolvedValues.getIndexedArgumentValues().values());
				valueHolders.addAll(resolvedValues.getGenericArgumentValues());
				for (ValueHolder value : valueHolders) {
					String argType = (value.getType() != null ? ClassUtils.getShortName(value.getType()) :
							(value.getValue() != null ? value.getValue().getClass().getSimpleName() : "null"));
					argTypes.add(argType);
				}
			}
			String argDesc = StringUtils.collectionToCommaDelimitedString(argTypes);
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"No matching factory method found: " +
					(mbd.getFactoryBeanName() != null ?
						"factory bean '" + mbd.getFactoryBeanName() + "'; " : "") +
					"factory method '" + mbd.getFactoryMethodName() + "(" + argDesc + ")'. " +
					"Check that a method with the specified name " +
					(minNrOfArgs > 0 ? "and arguments " : "") +
					"exists and that it is " +
					(isStatic ? "static" : "non-static") + ".");
		}
		else if (void.class == factoryMethodToUse.getReturnType()) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Invalid factory method '" + mbd.getFactoryMethodName() +
					"': needs to have a non-void return type!");
		}
		else if (ambiguousFactoryMethods != null) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Ambiguous factory method matches found in bean '" + beanName + "' " +
					"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
					ambiguousFactoryMethods);
		}

		if (explicitArgs == null && argsHolderToUse != null) {
			argsHolderToUse.storeCache(mbd, factoryMethodToUse);
		}
	}

	try {
		Object beanInstance;

		if (System.getSecurityManager() != null) {
			final Object fb = factoryBean;
			final Method factoryMethod = factoryMethodToUse;
			final Object[] args = argsToUse;
			beanInstance = AccessController.doPrivileged(new PrivilegedAction() {
				@Override
				public Object run() {
					return beanFactory.getInstantiationStrategy().instantiate(
							mbd, beanName, beanFactory, fb, factoryMethod, args);
				}
			}, beanFactory.getAccessControlContext());
		}
		else {
			//我们得到了工厂bean,方法,及方法参数,从而通过反射来调用工厂方法,从而获取相应的bean对象
			beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(
					mbd, beanName, this.beanFactory, factoryBean, factoryMethodToUse, argsToUse);
		}

		if (beanInstance == null) {
			return null;
		}
		bw.setWrappedInstance(beanInstance);
		return bw;
	}
	catch (Throwable ex) {
		throw new BeanCreationException(mbd.getResourceDescription(), beanName,
				"Bean instantiation via factory method failed", ex);
	}
}

ConstructorResolver.java

private int resolveConstructorArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw,
		ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) {

	TypeConverter converter = (this.beanFactory.getCustomTypeConverter() != null ?
			this.beanFactory.getCustomTypeConverter() : bw);
	BeanDefinitionValueResolver valueResolver =
			new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);

	int minNrOfArgs = cargs.getArgumentCount();

	for (Map.Entry<Integer, ConstructorArgumentValues.ValueHolder> entry : cargs.getIndexedArgumentValues().entrySet()) {
		int index = entry.getKey();
		if (index < 0) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Invalid constructor argument index: " + index);
		}
		if (index > minNrOfArgs) {
			minNrOfArgs = index + 1;
		}
		ConstructorArgumentValues.ValueHolder valueHolder = entry.getValue();
		if (valueHolder.isConverted()) {
			resolvedValues.addIndexedArgumentValue(index, valueHolder);
		}
		else {
			Object resolvedValue =
					valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
			ConstructorArgumentValues.ValueHolder resolvedValueHolder =
					new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName());
			resolvedValueHolder.setSource(valueHolder);
			resolvedValues.addIndexedArgumentValue(index, resolvedValueHolder);
		}
	}

	for (ConstructorArgumentValues.ValueHolder valueHolder : cargs.getGenericArgumentValues()) {
		if (valueHolder.isConverted()) {
			resolvedValues.addGenericArgumentValue(valueHolder);
		}
		else {
			Object resolvedValue =
					//得到转化后的值
					valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
			ConstructorArgumentValues.ValueHolder resolvedValueHolder =
					new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName());
			resolvedValueHolder.setSource(valueHolder);
			//将constructor-arg 的 value 值,保存到resolvedValues当中
			resolvedValues.addGenericArgumentValue(resolvedValueHolder);
		}
	}
	return minNrOfArgs;
}

SimpleInstantiationStrategy.java

public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner,
		Object factoryBean, final Method factoryMethod, Object... args) {

	try {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged(new PrivilegedAction() {
				@Override
				public Object run() {
					ReflectionUtils.makeAccessible(factoryMethod);
					return null;
				}
			});
		}
		else {
			ReflectionUtils.makeAccessible(factoryMethod);
		}

		Method priorInvokedFactoryMethod = currentlyInvokedFactoryMethod.get();
		try {
			currentlyInvokedFactoryMethod.set(factoryMethod);
			//通过反射获取bean对象
			return factoryMethod.invoke(factoryBean, args);
		}
		finally {
			if (priorInvokedFactoryMethod != null) {
				currentlyInvokedFactoryMethod.set(priorInvokedFactoryMethod);
			}
			else {
				currentlyInvokedFactoryMethod.remove();
			}
		}
	}
	catch (IllegalArgumentException ex) {
		throw new BeanInstantiationException(factoryMethod.getReturnType(),
				"Illegal arguments to factory method '" + factoryMethod.getName() + "'; " +
				"args: " + StringUtils.arrayToCommaDelimitedString(args), ex);
	}
	catch (IllegalAccessException ex) {
		throw new BeanInstantiationException(factoryMethod.getReturnType(),
				"Cannot access factory method '" + factoryMethod.getName() + "'; is it public?", ex);
	}
	catch (InvocationTargetException ex) {
		String msg = "Factory method '" + factoryMethod.getName() + "' threw exception";
		if (bd.getFactoryBeanName() != null && owner instanceof ConfigurableBeanFactory &&
				((ConfigurableBeanFactory) owner).isCurrentlyInCreation(bd.getFactoryBeanName())) {
			msg = "Circular reference involving containing bean '" + bd.getFactoryBeanName() + "' - consider " +
					"declaring the factory method as static for independence from its containing instance. " + msg;
		}
		throw new BeanInstantiationException(factoryMethod.getReturnType(), msg, ex.getTargetException());
	}
}

代码分析到这里己经感觉非常的简单了,我们来总结一下。
1.将xml中的属性factory-bean和factory-method保存到BeanDefinition相应的属性中,将constructor-arg的参数值保存到ConstructorArgumentValues的genericArgumentValues集合中。
2.当有工厂方法名时,调用instantiateUsingFactoryMethod这个方法来实例化bean .
3.在这个instantiateUsingFactoryMethod方法中主要通过方法名,方法参数个数,方法参数名称,以及方法参数类型,找出最匹配的工厂方法。
4.通过反射调用工厂方法得到实例。
5.将实例保存到容器的singletonObjects中。

本文的github地址
https://github.com/quyixiao/spring_tiny/tree/master/src/main/java/com/spring_1_100/test_41_50/test50

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值