spring IOC 之篇三:默认标签的解析

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标签的处理,其他都类似

 

/**
     * Process the given bean element, parsing the bean definition
     * and registering it with the registry.
     */
    protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {      
// 首先委托 BeanDefinitionParserDelegate 类的parseBeanDefinitionElement方法进行元素的解析,返回实例BeanDefinitionHolder 对象,经过这个方法后,bdHolder实例已经包含我们配置的配置文件中的各种属性了,列如:class,id,alias之类的属性了。
        BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
        if (bdHolder != null) {
// 当返回的BeanDefinitionHolder对象实例 bdHolder不为空的情况下若存在默认标签的字节点下再有自定义属性,还需要再次对自定义属性进行解析。
            bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
            try {
                // Register the final decorated instance.
//解析完成后,需要对解析后的bdHolder进行注册,同样,注册操作委托给了BeanDefinitionReaderUtils的registerBeanDefinition方法。
                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));
        }
    }

 

继续深入分析 BeanDefinitionParserDelegate 类的parseBeanDefinitionElement方法:

 

/**
     * 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}.
     */
    public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
       // 解析id属性
        String id = ele.getAttribute(ID_ATTRIBUTE);
      // 解析name属性
        String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
       // 分隔name属性 
        List<String> aliases = new ArrayList<String>();
        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.isDebugEnabled()) {
                logger.debug("No XML 'id' specified - using '" + beanName +
                        "' as bean name and " + aliases + " as aliases");
            }
        }

        if (containingBean == null) {
            checkNameUniqueness(beanName, aliases, ele);
        }
        // 进一步解析bean的其他属性 并封装到对象 GenericBeanDefinition对象中
        AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
        if (beanDefinition != null) {
            if (!StringUtils.hasText(beanName)) {
                try {
                    if (containingBean != null) {
              // 如果不存在 beanName,则使用Spring提供的命名规则默认生成beanName
                        beanName = BeanDefinitionReaderUtils.generateBeanName(
                                beanDefinition, this.readerContext.getRegistry(), true);
                    }
                    else {
        // 如果有则获取beanName
                        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.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);
// 将获取到的信息封装到
BeanDefinitionHolder 实例中去
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray); } return null; }

 

接下来进一步分析对其他bean标签的解析方法:

AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);

/**
     * 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.
     */
    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);
            }
          // 创建用于承载bean各种标签的 GenericBeanDefinition对象
            AbstractBeanDefinition bd = createBeanDefinition(className, parent);
           // 硬编码解析bean的属性 例如:singleton、destroy-method等
            parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
          // 提取 desciption
            bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
          // 解析元数据
            parseMetaElements(ele, bd);
          // 解析lookup-method属性
            parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
        // 解析repalce-method属性
            parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
       // 解析构造函数参数
            parseConstructorArgElements(ele, bd);
     // 解析property字元素
            parsePropertyElements(ele, bd);
     // 解析qualifier子元素
            parseQualifierElements(ele, bd);
 
            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();
        }

        return null;
    }

进一步分析创建属性承载的BeanDefinition对象

BeanDefinition是一个接口,spring中三种实现形式:RootBeanDefinitionChildBeanDefinitionGenericBeanDefinition。三种实现类均继承了AbstractBeanDefinition,其中BeanDefinition<bean>标签在容器内部的表现形式,BeanDefinition<bean>的属性是一一对应的。Spring通过BeanDefinition将配置文件中的信息装换为内部的表现形式,并将这些BeanDefinition注册到BeanDefinitionRegistry中。

 至此 已经完成XML文档像GenericBeandefinition的全部装换。GenericBeandefinition只是子类实现,大部分属性封装在AbstractBeandefinition对象中,我们继续分析AbstractBeandefinition的给中属性:

@SuppressWarnings("serial")
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
        implements BeanDefinition, Cloneable {

    /**
     * Constant for the default scope name: {@code ""}, equivalent to singleton
     * status unless overridden from a parent bean definition (if applicable).
     */
    public static final String SCOPE_DEFAULT = "";

    /**
     * Constant that indicates no autowiring at all.
     * @see #setAutowireMode
     */
    public static final int AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO;

    /**
     * Constant that indicates autowiring bean properties by name.
     * @see #setAutowireMode
     */
    public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;

    /**
     * Constant that indicates autowiring bean properties by type.
     * @see #setAutowireMode
     */
    public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;

    /**
     * Constant that indicates autowiring a constructor.
     * @see #setAutowireMode
     */
    public static final int AUTOWIRE_CONSTRUCTOR = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR;

    /**
     * Constant that indicates determining an appropriate autowire strategy
     * through introspection of the bean class.
     * @see #setAutowireMode
     * @deprecated as of Spring 3.0: If you are using mixed autowiring strategies,
     * use annotation-based autowiring for clearer demarcation of autowiring needs.
     */
    @Deprecated
    public static final int AUTOWIRE_AUTODETECT = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT;

    /**
     * Constant that indicates no dependency check at all.
     * @see #setDependencyCheck
     */
    public static final int DEPENDENCY_CHECK_NONE = 0;

    /**
     * Constant that indicates dependency checking for object references.
     * @see #setDependencyCheck
     */
    public static final int DEPENDENCY_CHECK_OBJECTS = 1;

    /**
     * Constant that indicates dependency checking for "simple" properties.
     * @see #setDependencyCheck
     * @see org.springframework.beans.BeanUtils#isSimpleProperty
     */
    public static final int DEPENDENCY_CHECK_SIMPLE = 2;

    /**
     * Constant that indicates dependency checking for all properties
     * (object references as well as "simple" properties).
     * @see #setDependencyCheck
     */
    public static final int DEPENDENCY_CHECK_ALL = 3;

    /**
     * Constant that indicates the container should attempt to infer the
     * {@link #setDestroyMethodName destroy method name} for a bean as opposed to
     * explicit specification of a method name. The value {@value} is specifically
     * designed to include characters otherwise illegal in a method name, ensuring
     * no possibility of collisions with legitimately named methods having the same
     * name.
     * <p>Currently, the method names detected during destroy method inference
     * are "close" and "shutdown", if present on the specific bean class.
     */
    public static final String INFER_METHOD = "(inferred)";


    private volatile Object beanClass;
   // bean的作用范围,对应bean的属性 scope
    private String scope = SCOPE_DEFAULT;
 // 是否抽象标识,默认false,对应bean的属性 abstract
    private boolean abstractFlag = false;
 // 是否延迟加载,对应bean的属性 lazy-init
    private boolean lazyInit = false;
 // 是否自动注入模式,对应bean的属性autowire
    private int autowireMode = AUTOWIRE_NO;
// 依赖检查,spring3以后弃用这个属性
    private int dependencyCheck = DEPENDENCY_CHECK_NONE;
// 用来表示一个bean的实例化,依赖另一个bean实例化,对应bean的属性depend-on
    private String[] dependsOn;
// autowire-candidate属性设置为false,这样容器在查找自动装配对象的时候,将不会考虑该bean,即不会考虑该bean作为其他bean的自动装配候选者
    private boolean autowireCandidate = true;
// 当自动装配出现多个bean,如果primary为true,则改bean作为首席候选者
    private boolean primary = false;
// 用于记录 Qualifier 对应子元素 qualifier
    private final Map<String, AutowireCandidateQualifier> qualifiers =
            new LinkedHashMap<String, AutowireCandidateQualifier>(0);

    private boolean nonPublicAccessAllowed = true;

    private boolean lenientConstructorResolution = true;
    
//记录构造函数注入属性,对应属性值 constructor-arg
    private ConstructorArgumentValues ArgumentValues;
// 普通属性集合
    private MutablePropertyValues propertyValues;
// 记录 lookup-method和replace-method属性值
    private MethodOverrides methodOverrides = new MethodOverrides();

    private String factoryBeanName;

    private String factoryMethodName;
// 初始化方法 对应属性 init-method
    private String initMethodName;
// 销毁方法 对应属性 destroy-method
private String destroyMethodName;
// 是否执行 init-method 程序设置
    private boolean enforceInitMethod = true;
// 是否执行 destroy-method 程序设置
    private boolean enforceDestroyMethod = true;

   // 使用用户自定义而不是应用程序本身定义的,创建AOP时候为true
 private boolean synthetic = false;

    private int role = BeanDefinition.ROLE_APPLICATION;

private String description; 
// 这个bean定义的资源
    private Resource resource;

 

解析完成以后,会将所有的xml属性值封装至对象 GenericBeanDefinition中,然后会进行注册。

针对以下代码进行分析:

BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry())

// 解析完以后,BeanDefinition对象就注册到了BeanDefinitionRegisty集合中去了。将beanName作为Key,BeanDefinition作为value

 

/**
     * Register the given bean definition with the given bean factory.
     * @param definitionHolder the bean definition including name and aliases
     * @param registry the bean factory to register with
     * @throws BeanDefinitionStoreException if registration failed
     */
    public static void registerBeanDefinition(
            BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
            throws BeanDefinitionStoreException {

        // Register bean definition under primary name.
       // 使用beanName作为唯一注册标识
        String beanName = definitionHolder.getBeanName();
        registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

        // Register aliases for bean name, if any.
       // 注册所有的bean的别名
        String[] aliases = definitionHolder.getAliases();
        if (aliases != null) {
            for (String alias : aliases) {
                registry.registerAlias(beanName, alias);
            }
        }
    }

 

继续深入解析:

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 {
        // 注册前的最后一次校验,这里主要校验AbstractBeandefinition 中的methodOverrides 属性,校验methodOverrides是否与工厂方法共存,或者对应的方法根本不存在
                ((AbstractBeanDefinition) beanDefinition).validate();
            }
            catch (BeanDefinitionValidationException ex) {
                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
                        "Validation of bean definition failed", ex);
            }
        }

        BeanDefinition oldBeanDefinition;

        oldBeanDefinition = this.beanDefinitionMap.get(beanName);
        if (oldBeanDefinition != null) {
      // 对于已经注册过的bean,如果不允许覆盖,则直接抛出异常
            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 {
            if (hasBeanCreationStarted()) {
                // Cannot modify startup-time collection elements anymore (for stable iteration)
//因为 beanDefinitionMap 是全局变量,这里会存在并发的情况
                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
             // 注册beanDefinition
                this.beanDefinitionMap.put(beanName, beanDefinition);
            // 记录所有的beanNames
                this.beanDefinitionNames.add(beanName);
                this.manualSingletonNames.remove(beanName);
            }
            this.frozenBeanDefinitionNames = null;
        }

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

注册完成,通知所有的监听事件:

getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));

这里是spring留给子类进行扩展的。

 

posted @ 2018-05-01 21:28  烟尘  阅读(284)  评论(1编辑  收藏  举报