由于字数超过了限制,因此分红了三篇,承接上篇:
https://www.jianshu.com/p/a0cfaedf3fc5java
代码过宽,能够shift + 鼠标滚轮 左右滑动查看node
先跟踪一个bean标签,下面是对应的配置文件spring
<!--配置mapper.java扫描--> <bean class="tk.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="cn.mrdear.mapper"/> <property name="properties"> <value> mappers=tk.mybatis.mapper.common.Mapper </value> </property> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> </bean>
由于是bean标签,走的默认的名称空间方法,因此走这个标签的方法:sql
//3.若是该标签属于beans的名称空间,则进入这个方法 //xmlns="http://www.springframework.org/schema/beans" parseDefaultElement(ele, delegate);
这个方法的实如今DefaultBeanDefinitionDocumentReader类中,由于
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 // 若是是嵌套的beans,那么就会从新调用标记2中的一个方法进行递归 doRegisterBeanDefinitions(ele); } } /** * Process the given bean element, parsing the bean definition * and registering it with the registry. * * 处理bean元素,解析成bean definition并注册到工厂中 */ protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { //3.1经过代理解析bean元素 BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); if (bdHolder != null) { //3.2若是有要求的话渲染beanDefinition bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder); try { // Register the final decorated instance. //3.3注册最终被渲染的实例到工厂中 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)); } }
跟踪3.1标记的方法mybatis
进入BeanDefinitionParserDelegate类的parseBeanDefinitionElement方法app
//3.1经过代理解析bean元素 BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); /** * Parses the supplied {@code <bean>} element. May return {@code null} * if there were errors during parse. Errors are reported to the * {@link org.springframework.beans.factory.parsing.ProblemReporter}. * * 解析bean元素。若是解析过程当中发生错误则返回空 */ public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) { return parseBeanDefinitionElement(ele, null); } public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) { //拿bean标签上的id String id = ele.getAttribute(ID_ATTRIBUTE); //拿bean标签上的name属性 String nameAttr = ele.getAttribute(NAME_ATTRIBUTE); List<String> aliases = new ArrayList<String>(); //有name属性进入 if (StringUtils.hasLength(nameAttr)) { //name属性对应的name值若是有分隔符",; ",那么切分红数组 String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS); //这些name值就是别名 aliases.addAll(Arrays.asList(nameArr)); } //指定了id就用id值做为bean名称 String beanName = id; //若是没有id,可是指定了name,就用name值做为bean名称 if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) { //拿第一个name值做为bean名称,其他的仍是别名 beanName = aliases.remove(0); if (logger.isDebugEnabled()) { logger.debug("No XML 'id' specified - using '" + beanName + "' as bean name and " + aliases + " as aliases"); } } if (containingBean == null) { //检查bean名称和别名是否已经被使用了,若是用了就报错 //同时把这个bean的名称和别名加入代理的usedNames属性中 //private final Set<String> usedNames = new HashSet<String>(); checkNameUniqueness(beanName, aliases, ele); } //直接进入这个方法 AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean); if (beanDefinition != null) { //既没有指定id,也没有指定name就走这里面 if (!StringUtils.hasText(beanName)) { try { //前面containingBean传递时为null,这里不走这个方法 if (containingBean != null) { beanName = BeanDefinitionReaderUtils.generateBeanName( beanDefinition, this.readerContext.getRegistry(), true); } else { //生成一个bean名称,beanName //若是这个bean是内部bean,全限定名后加#号再加哈希值 //若是是顶层bean,那么后面加#号再从0开始加数字,id已被注册数字就增1,直到惟一 //好比:tk.mybatis.spring.mapper.MapperScannerConfigurer#0 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)) { //若是该类名没有被使用,那么注册该类名做为别名,好比: //tk.mybatis.spring.mapper.MapperScannerConfigurer做为 //tk.mybatis.spring.mapper.MapperScannerConfigurer#0的别名 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); //返回beanDefinition的持有者 return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray); } return null; } /** * Parse the bean definition itself, without regard to name or aliases. May return * {@code null} if problems occurred during the parsing of the bean definition. * * 不关注名称和别名,只解析bean definition自身 */ public AbstractBeanDefinition parseBeanDefinitionElement( Element ele, String beanName, BeanDefinition containingBean) { //解析的时候放入,解析完成弹出,这里放入bean标签, //若是还嵌套有子标签,则后续放入子标签 //子标签先弹出 this.parseState.push(new BeanEntry(beanName)); String className = null; if (ele.hasAttribute(CLASS_ATTRIBUTE)) { //若是有指定class属性,则拿到class属性值 className = ele.getAttribute(CLASS_ATTRIBUTE).trim(); } try { String parent = null; if (ele.hasAttribute(PARENT_ATTRIBUTE)) { //若是有指定parent属性,则拿到parent属性值 parent = ele.getAttribute(PARENT_ATTRIBUTE); } //3.1.1建立BeanDefinition并设置两属性 AbstractBeanDefinition bd = createBeanDefinition(className, parent); //3.1.2将bean标签上的属性设置到bean definition中 parseBeanDefinitionAttributes(ele, beanName, containingBean, bd); //若是bean标签下有子标签为description,拿到标签中的文本,设置到bean definition中 bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT)); //若是bean标签下有子标签为meta,拿到他的key和value属性,设置到bean definition中 parseMetaElements(ele, bd); //若是bean标签下有子标签为lookup-method,拿到他的name和bean属性,设置到bean definition中 parseLookupOverrideSubElements(ele, bd.getMethodOverrides()); //若是bean标签下有子标签为replaced-method,设置bean definition parseReplacedMethodSubElements(ele, bd.getMethodOverrides()); //若是bean标签下有子标签为constructor-arg,设置bean definition的构造方式 parseConstructorArgElements(ele, bd); //这个标签比较经常使用,为Property标签 //3.1.3解析Property的属性设置到bean definition中 parsePropertyElements(ele, bd); //有qualifier子标签才走这个方法 parseQualifierElements(ele, bd); //设置资源 bd.setResource(this.readerContext.getResource()); //这里为null 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(); } return null; }
跟踪标记3.1.1ide
//3.1.1建立BeanDefinition并设置两属性 AbstractBeanDefinition bd = createBeanDefinition(className, parent); /** * Create a bean definition for the given class name and parent name. * * 经过给定的className和parentName建立beanDefinition */ protected AbstractBeanDefinition createBeanDefinition(String className, String parentName) throws ClassNotFoundException { return BeanDefinitionReaderUtils.createBeanDefinition( parentName, className, this.readerContext.getBeanClassLoader()); } /** * 此方法是BeanDefinitionReaderUtils的静态方法 * * Create a new GenericBeanDefinition for the given parent name and class name, * eagerly loading the bean class if a ClassLoader has been specified. * * 经过给定的parentName和className穿件一个新的GenericBeanDefinition * 若是指定了ClassLoader,就提早加载bean class */ public static AbstractBeanDefinition createBeanDefinition( String parentName, String className, ClassLoader classLoader) throws ClassNotFoundException { GenericBeanDefinition bd = new GenericBeanDefinition(); bd.setParentName(parentName); if (className != null) { if (classLoader != null) { //接受的属性是Object类型 bd.setBeanClass(ClassUtils.forName(className, classLoader)); } else { //接受的属性是Object类型 bd.setBeanClassName(className); } } return bd; }
跟踪标记方法3.1.2ui
此方法在BeanDefinitionParserDelegate类中this
//3.1.2将bean标签上的属性设置到bean definition中 parseBeanDefinitionAttributes(ele, beanName, containingBean, bd); /** * Apply the attributes of the given bean element to the given bean * definition. * * 将bean标签上的属性设置到bean definition中 */ public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName, BeanDefinition containingBean, AbstractBeanDefinition bd) { //bean标签上已经没有singleton属性了,用scope代替,因此出现就报错 if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) { error("Old 1.x 'singleton' attribute in use - upgrade to 'scope' declaration", ele); } //若是设置了scope就拿其值 else if (ele.hasAttribute(SCOPE_ATTRIBUTE)) { bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE)); } //此处containingBean为空 else if (containingBean != null) { // Take default from containing bean in case of an inner bean definition. // 若是是一个内部的bean definition,用包含的bean的default bd.setScope(containingBean.getScope()); } //是否有abstract属性 if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) { bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE))); } String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE); //lazyInit若是没有设置则为默认值,默认值用的代理类中defaults属性, //也就是this.defaults if (DEFAULT_VALUE.equals(lazyInit)) { lazyInit = this.defaults.getLazyInit(); } bd.setLazyInit(TRUE_VALUE.equals(lazyInit)); //默认值用的代理类中defaults属性,不进行autowire String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE); bd.setAutowireMode(getAutowireMode(autowire)); //默认不进行依赖检查 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 { //没有init-method属性,就拿代理类defaults属性的 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 { //没有destroy-method属性,就拿代理类defaults属性的 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; }
这样,bean标签上的属性也就解析完成了,对其属性的描述无论设置了仍是没有设置的,都有相应的值对应到bean definition中。接下来就要解析,bean标签下的子标签了。
跟踪3.1.3标记的方法
此方法在BeanDefinitionParserDelegate类中实现
//3.1.3解析Property的属性设置到bean definition中 parsePropertyElements(ele, bd); /** * Parse property sub-elements of the given bean element. * 解析bean标签下property子标签 */ public void parsePropertyElements(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, PROPERTY_ELEMENT)) { //标签名为property才能进入,进入这个方法 parsePropertyElement((Element) node, bd); } } } /** * Parse a property element. */ public void parsePropertyElement(Element ele, BeanDefinition bd) { //拿到property标签的name属性 String propertyName = ele.getAttribute(NAME_ATTRIBUTE); if (!StringUtils.hasLength(propertyName)) { error("Tag 'property' must have a 'name' attribute", ele); return; } //解析的时候放入,解析完成弹出,这里放入property标签, //这里面还存有bean父标签,子标签解析完成后先弹出 this.parseState.push(new PropertyEntry(propertyName)); try { //bean标签下能够有多个property,可是不能重复name属性 if (bd.getPropertyValues().contains(propertyName)) { error("Multiple 'property' definitions for property '" + propertyName + "'", ele); return; } //进入这个方法,查看是怎么解析property标签属性的 Object val = parsePropertyValue(ele, bd, propertyName); //将name属性和对应的value放入 PropertyValue pv = new PropertyValue(propertyName, val); //解析property标签的子标签meta, //拿到meta的key和value属性,设置到PropertyValue中 parseMetaElements(ele, pv); //这里没有实现,为null pv.setSource(extractSource(ele)); //将PropertyValue添加到bean definition中 bd.getPropertyValues().addPropertyValue(pv); } finally { //解析的时候放入,解析完成弹出,这里放入property标签 this.parseState.pop(); } } /** * Get the value of a property element. May be a list etc. * Also used for constructor arguments, "propertyName" being null in this case. * * 拿到property标签的value值,多是list * 也被constructor标签使用,这种状况propertyName为null */ public Object parsePropertyValue(Element ele, BeanDefinition bd, String propertyName) { //若是propertyName为null,则是constructor-arg标签 //不然为property标签 String elementName = (propertyName != null) ? "<property> element for property '" + propertyName + "'" : "<constructor-arg> element"; // Should only have one child element: ref, value, list, etc. //不论是哪一种标签,下面都应该只有一个子标签: ref, value, list等. NodeList nl = ele.getChildNodes(); Element subElement = null; for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); if (node instanceof Element && !nodeNameEquals(node, DESCRIPTION_ELEMENT) && !nodeNameEquals(node, META_ELEMENT)) { // Child element is what we're looking for. //除开description和meta标签,子标签最多只能有一个 if (subElement != null) { error(elementName + " must not contain more than one sub-element", ele); } else { subElement = (Element) node; } } } //看标签属性用的是value仍是ref boolean hasRefAttribute = ele.hasAttribute(REF_ATTRIBUTE); boolean hasValueAttribute = ele.hasAttribute(VALUE_ATTRIBUTE); //value和ref属性不能同时存在,若是有子标签,则value和ref都不能存在,不然报错 if ((hasRefAttribute && hasValueAttribute) || ((hasRefAttribute || hasValueAttribute) && subElement != null)) { error(elementName + " is only allowed to contain either 'ref' attribute OR 'value' attribute OR sub-element", ele); } //用的ref的状况 if (hasRefAttribute) { String refName = ele.getAttribute(REF_ATTRIBUTE); if (!StringUtils.hasText(refName)) { error(elementName + " contains empty 'ref' attribute", ele); } RuntimeBeanReference ref = new RuntimeBeanReference(refName); ref.setSource(extractSource(ele)); return ref; } //用的value的状况 else if (hasValueAttribute) { TypedStringValue valueHolder = new TypedStringValue(ele.getAttribute(VALUE_ATTRIBUTE)); valueHolder.setSource(extractSource(ele)); return valueHolder; } //子标签不为null的状况,进入这个方法查看 else if (subElement != null) { return parsePropertySubElement(subElement, bd); } else { // Neither child element nor "ref" or "value" attribute found. //没指定ref或者value或者子标签,返回null error(elementName + " must specify a ref or value", ele); return null; } } /** * 这个方法仍是在BeanDefinitionParserDelegate中 */ public Object parsePropertySubElement(Element ele, BeanDefinition bd) { return parsePropertySubElement(ele, bd, null); } /** * Parse a value, ref or collection sub-element of a property or * constructor-arg element. * * 解析property或者constructor-arg标签的子标签,可能为value, ref或者集合 */ public Object parsePropertySubElement(Element ele, BeanDefinition bd, String defaultValueType) { //若是这个子标签不属于beans的名称空间,则走这个方法 if (!isDefaultNamespace(ele)) { return parseNestedCustomElement(ele, bd); } //若是是bean子标签,则走这个方法 else if (nodeNameEquals(ele, BEAN_ELEMENT)) { BeanDefinitionHolder nestedBd = parseBeanDefinitionElement(ele, bd); if (nestedBd != null) { nestedBd = decorateBeanDefinitionIfRequired(ele, nestedBd, bd); } return nestedBd; } //若是是ref子标签,则走这个方法 else if (nodeNameEquals(ele, REF_ELEMENT)) { // A generic reference to any name of any bean. String refName = ele.getAttribute(BEAN_REF_ATTRIBUTE); boolean toParent = false; if (!StringUtils.hasLength(refName)) { // A reference to the id of another bean in the same XML file. refName = ele.getAttribute(LOCAL_REF_ATTRIBUTE); if (!StringUtils.hasLength(refName)) { // A reference to the id of another bean in a parent context. refName = ele.getAttribute(PARENT_REF_ATTRIBUTE); toParent = true; if (!StringUtils.hasLength(refName)) { error("'bean', 'local' or 'parent' is required for <ref> element", ele); return null; } } } if (!StringUtils.hasText(refName)) { error("<ref> element contains empty target attribute", ele); return null; } RuntimeBeanReference ref = new RuntimeBeanReference(refName, toParent); ref.setSource(extractSource(ele)); return ref; } //若是是idref子标签,则走这个方法 else if (nodeNameEquals(ele, IDREF_ELEMENT)) { return parseIdRefElement(ele); } //若是是value子标签,则走这个方法 else if (nodeNameEquals(ele, VALUE_ELEMENT)) { //以这个方法做为演示,其余的方法都是大同小异,进入。 return parseValueElement(ele, defaultValueType); } //若是是null子标签,则走这个方法 else if (nodeNameEquals(ele, NULL_ELEMENT)) { // It's a distinguished null value. Let's wrap it in a TypedStringValue // object in order to preserve the source location. TypedStringValue nullHolder = new TypedStringValue(null); nullHolder.setSource(extractSource(ele)); return nullHolder; } //若是是array子标签,则走这个方法 else if (nodeNameEquals(ele, ARRAY_ELEMENT)) { return parseArrayElement(ele, bd); } //若是是list子标签,则走这个方法 else if (nodeNameEquals(ele, LIST_ELEMENT)) { return parseListElement(ele, bd); } //若是是set子标签,则走这个方法 else if (nodeNameEquals(ele, SET_ELEMENT)) { return parseSetElement(ele, bd); } //若是是map子标签,则走这个方法 else if (nodeNameEquals(ele, MAP_ELEMENT)) { return parseMapElement(ele, bd); } //若是是props子标签,则走这个方法 else if (nodeNameEquals(ele, PROPS_ELEMENT)) { return parsePropsElement(ele); } //不然返回null,报错 else { error("Unknown property sub-element: [" + ele.getNodeName() + "]", ele); return null; } } /** * Return a typed String value Object for the given value element. * * 经过指定的value标签,返回指定的字符串value对象 */ public Object parseValueElement(Element ele, String defaultTypeName) { // It's a literal value. //拿到value中的文本,包括回车、tab制表符、空格 String value = DomUtils.getTextValue(ele); //有无type属性 String specifiedTypeName = ele.getAttribute(TYPE_ATTRIBUTE); String typeName = specifiedTypeName; if (!StringUtils.hasText(typeName)) { //没有就用入参defaultTypeName typeName = defaultTypeName; } try { TypedStringValue typedValue = buildTypedStringValue(value, typeName); //这里设置为空 typedValue.setSource(extractSource(ele)); //这里为空字符串 typedValue.setSpecifiedTypeName(specifiedTypeName); //返回typedValue return typedValue; } catch (ClassNotFoundException ex) { error("Type class [" + typeName + "] not found for <value> element", ele, ex); return value; } }
在生成了BeanDefinitionHolder之后,若是须要的话应该经过代理类对bean definition进行渲染。
跟踪标记3.2的方法
该方法的实如今BeanDefinitionParserDelegate类中
//3.2若是有要求的话渲染beanDefinition bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder); public BeanDefinitionHolder decorateBeanDefinitionIfRequired(Element ele, BeanDefinitionHolder definitionHolder) { return decorateBeanDefinitionIfRequired(ele, definitionHolder, null); } public BeanDefinitionHolder decorateBeanDefinitionIfRequired( Element ele, BeanDefinitionHolder definitionHolder, BeanDefinition containingBd) { BeanDefinitionHolder finalDefinition = definitionHolder; // Decorate based on custom attributes first. // 首先基于自定义属性进行渲染 // 也就是bean标签上的属性,也就是node // 只有当这个node不属于名称空间beans才会进行渲染,这里就不进去看了 NamedNodeMap attributes = ele.getAttributes(); for (int i = 0; i < attributes.getLength(); i++) { Node node = attributes.item(i); finalDefinition = decorateIfRequired(node, finalDefinition, containingBd); } // Decorate based on custom nested elements. // 而后根据标签内嵌套的子标签进行渲染 // 这里是不属于名称空间beans的子标签才会进行渲染 NodeList children = ele.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { Node node = children.item(i); if (node.getNodeType() == Node.ELEMENT_NODE) { finalDefinition = decorateIfRequired(node, finalDefinition, containingBd); } } return finalDefinition; }
最终将完成的bean definition注册到工厂中
跟踪标记3.3的方法
//3.3注册最终被渲染的实例到工厂中 BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()); /** * Register the given bean definition with the given bean factory. * * 注册bean definition */ public static void registerBeanDefinition( BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException { // Register bean definition under primary name. // 3.3.1注册bean definition的beanName // 好比tk.mybatis.spring.mapper.MapperScannerConfigurer#0 String beanName = definitionHolder.getBeanName(); registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); // Register aliases for bean name, if any. // 若是有别名的话,为bean name注册别名 String[] aliases = definitionHolder.getAliases(); if (aliases != null) { for (String alias : aliases) { //3.3.2注册别名 registry.registerAlias(beanName, alias); } } }
跟踪标记3.3.1的方法
// 3.3.1注册bean definition的beanName registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); @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 { //作一个验证,静态工厂方法和覆盖方法不能组合使用 //若是bean definition中的beanClass属性不是String类型而是Class类型 //那么就要验证和准备这个bean定义的覆盖方法,检查指定名称的方法是否存在 ((AbstractBeanDefinition) beanDefinition).validate(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", ex); } } BeanDefinition oldBeanDefinition; //查看beanName是否已经被注册在工厂的beanDefinitionMap属性中 oldBeanDefinition = this.beanDefinitionMap.get(beanName); //已经被注册走这个方法,这里不查看 if (oldBeanDefinition != null) { if (!isAllowBeanDefinitionOverriding()) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName + "': There is already [" + oldBeanDefinition + "] bound."); } else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) { // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE if (this.logger.isWarnEnabled()) { this.logger.warn("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]"); } } else if (!beanDefinition.equals(oldBeanDefinition)) { if (this.logger.isInfoEnabled()) { this.logger.info("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]"); } } else { if (this.logger.isDebugEnabled()) { this.logger.debug("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]"); } } this.beanDefinitionMap.put(beanName, beanDefinition); } else { //这里面表明beanName尚未被注册 //而后根据阶段不一样又有一层判断 if (hasBeanCreationStarted()) { //这个阶段是bean已经开始建立 // Cannot modify startup-time collection elements anymore (for stable iteration) synchronized (this.beanDefinitionMap) { this.beanDefinitionMap.put(beanName, beanDefinition); List<String> updatedDefinitions = new ArrayList<String>(this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); this.beanDefinitionNames = updatedDefinitions; if (this.manualSingletonNames.contains(beanName)) { Set<String> updatedSingletons = new LinkedHashSet<String>(this.manualSingletonNames); updatedSingletons.remove(beanName); this.manualSingletonNames = updatedSingletons; } } } else { // Still in startup registration phase // 仍然处于启动时的注册阶段 // 因此这里走这个方法 //beanDefinitionMap是工厂的一个属性,ConcurrentHashMap类型 //他保存全部解析好的bean Definition的名称和实例的映射 this.beanDefinitionMap.put(beanName, beanDefinition); //beanName也单独使用了一个ArrayList来保存,方便遍历 this.beanDefinitionNames.add(beanName); //若是该bean definition是手动注册的,还要从manualSingletonNames中 //移除bean definition的beanName,还要从manualSingletonNames中是LinkedHashSet this.manualSingletonNames.remove(beanName); } this.frozenBeanDefinitionNames = null; } //这里跳过 if (oldBeanDefinition != null || containsSingleton(beanName)) { resetBeanDefinition(beanName); } }
跟踪3.3.2方法
//3.3.2注册别名 registry.registerAlias(beanName, alias); @Override public void registerAlias(String name, String alias) { Assert.hasText(name, "'name' must not be empty"); Assert.hasText(alias, "'alias' must not be empty"); if (alias.equals(name)) { //移除别名中的beanName //aliasMap是ConcurrentHashMap类型,保存别名和beanName的映射 this.aliasMap.remove(alias); } else { String registeredName = this.aliasMap.get(alias); //若是别名对应beanName已经被注册,则不须要再注册一次 //别名不容许被覆盖 if (registeredName != null) { if (registeredName.equals(name)) { // An existing alias - no need to re-register return; } if (!allowAliasOverriding()) { throw new IllegalStateException("Cannot register alias '" + alias + "' for name '" + name + "': It is already registered for name '" + registeredName + "'."); } } //再检查一遍,aliasMap中不能已经存在name和alias checkForAliasCircle(name, alias); //工厂的aliasMap属性保存别名,那么alias已被注册 this.aliasMap.put(alias, name); } }
这样,spring配置文件中为bean标签的解析和加载,也就跟踪完了。
而后再看下非默认名称空间的标签的解析和加载。
由于字数超过了限制,因此分红了三篇,点击下篇继续阅读
https://www.jianshu.com/p/6e0f6fd1cbbd
beans名称空间
下,不一样的标签有不一样的子方法,对于<bean>
标签来讲,主要分为三步:
——————————————————————————————————
——————————————————————————————————