Spring source code analysis (4) How does Spring handle BeanDefinition?

In the previous article, we analyzed how BeanDefinition is parsed. In this article, we mainly look at what we do after parsing;

一、DefaultBeanDefinitionDocumentReader


Source code entry

processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate)

    /**
     * Process the given bean element, parsing the bean definition
     * and registering it with the registry.
     */
    protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
        //这个bdHoder就是被解析完成之后的BeanDefinition;上篇分析了,这里不再赘述
        BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
        if (bdHolder != null) {
            //这里是修饰一下BeanDefinition,这里以后再单独分析;TODO...
            bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
            try {

                /**注册BeanDefinition;
                *1.DefaultBeanDefinitionDocumentReader里面持有XmlReaderContext readerContext;
                *2.XmlReaderContext extends AbstractBeanDefinitionReader,这个类里面持有BeanDefinitionRegistry registry;注册器;registry默认实现 DefaultListableBeanFactory
                */
                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));
        }
    }

Second, BeanDefinitionReaderUtils


EVERYTHING…

registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)

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

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

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

三、DefaultListableBeanFactory


EVERYTHING

registerBeanDefinition (String beanName, BeanDefinition beanDefinition)

    /** 缓存所有的BeanDefinition */
    private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(256);

    /** 已注册的所有 BeanDefinition name*/
    private volatile List<String> beanDefinitionNames = new ArrayList<String>(256);
    /** List of names of manually registered singletons, in registration order */
    /** 单例对象注册清单 */
    private volatile Set<String> manualSingletonNames = new LinkedHashSet<String>(16);

    /** Cached array of bean definition names in case of frozen configuration */
    private volatile String[] frozenBeanDefinitionNames;

@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 {
                /**
                *1.验证definition,如果getMethodOverrides().isNotEmpty() && getFactoryMethodName() != null 就抛异常;
                MethodOverrides在我们上一篇文章中的LookupOverride、ReplaceOverride被设置过;这行代码意思是如果设置了 MethodOverrides效果,则不能同时存在工厂方法;如下图中同时设置就会报错了
                *2.if (hasBeanClass()) {
                        prepareMethodOverrides();
                    }
                如果(this.beanClass instanceof Class) 这个beanClass在上一篇了解到,创建BeanDefinition的时候如果有ClassLoader就通过返回拿到Class对象;
                *3.bd的overrides做一些处理;
                */

                ((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) {
            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 {
            //判断factory's 是否开始创建了;什么时候开始呢?TODO...回头单独分析
            if (hasBeanCreationStarted()) {
                // Cannot modify startup-time collection elements anymore (for stable iteration)
                synchronized (this.beanDefinitionMap) {
                    //注册beanDefinition到map中
                    this.beanDefinitionMap.put(beanName, beanDefinition);
                    //下面这种处理为什么不直接this.beanDefinitionNames.add(beanName)?
                    //大概是因为List是线程不安全的把;如果有线程在遍历,这里修改就会有问题了,所以直接新建一个list赋值过去
                    List<String> updatedDefinitions = new ArrayList<String>(this.beanDefinitionNames.size() + 1);
                    updatedDefinitions.addAll(this.beanDefinitionNames);
                    updatedDefinitions.add(beanName);
                    this.beanDefinitionNames = updatedDefinitions;
                    //判断 manualSingletonNames单例对象中是否存在相同的对象名,如果存在就表示不是单例对象了,就在manualSingletonNames中remove掉
                    if (this.manualSingletonNames.contains(beanName)) {
                        Set<String> updatedSingletons = new LinkedHashSet<String>(this.manualSingletonNames);
                        updatedSingletons.remove(beanName);
                        this.manualSingletonNames = updatedSingletons;
                    }
                }
            }
            else {
                // 还在启动注册阶段
                this.beanDefinitionMap.put(beanName, beanDefinition);
                this.beanDefinitionNames.add(beanName);
                this.manualSingletonNames.remove(beanName);
            }
            this.frozenBeanDefinitionNames = null;
        }

        if (oldBeanDefinition != null || containsSingleton(beanName)) {
            resetBeanDefinition(beanName);
        }
    }

AbstractBeanDefinition validate()

    public void validate() throws BeanDefinitionValidationException {
        if (!getMethodOverrides().isEmpty() && getFactoryMethodName() != null) {
            throw new BeanDefinitionValidationException(
                    "Cannot combine static factory method with method overrides: " +
                    "the static factory method must create the instance");
        }

        if (hasBeanClass()) {
            prepareMethodOverrides();
        }
    }
/**
     * Validate and prepare the method overrides defined for this bean.
     * Checks for existence of a method with the specified name.
     * @throws BeanDefinitionValidationException in case of validation failure
     */
    public void prepareMethodOverrides() throws BeanDefinitionValidationException {
        // Check that lookup methods exists. 查看是否有设置lookup
        MethodOverrides methodOverrides = getMethodOverrides();
        if (!methodOverrides.isEmpty()) {
            Set<MethodOverride> overrides = methodOverrides.getOverrides();
            synchronized (overrides) {
                for (MethodOverride mo : overrides) {
                    prepareMethodOverride(mo);
                }
            }
        }
    }
protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
        //查找这个beanClass的所有跟mo.getMethodName()相等的描述方法、接口数量
        int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
        if (count == 0) {
            throw new BeanDefinitionValidationException(
                    "Invalid method override: no method with name '" + mo.getMethodName() +
                    "' on class [" + getBeanClassName() + "]");
        }
        //如果只有一个 则更新overloaded的属性为false;
        else if (count == 1) {
            // Mark override as not overloaded, to avoid the overhead of arg type checking.
            //标记这个mo不是 重载,而是覆盖;避免参数类型检查的开销。默认是true
            mo.setOverloaded(false);
        }
    }   

validate

4. Summary

The above is just a brief analysis of the place of BeanDefinition, and found that BeanDefinition was later registered in DefaultListableBeanFactory; this stores all BeanDefinition references;
there are still some problems that are not clear;
1.delegate.decorateBeanDefinitionIfRequired Modifies BeanDefinition analysis?
2.hasBeanCreationStarted() Judge whether there is a bean sentence started to create?
3.registerSingleton register singleton analysis?

The above will wait for the next time to analyze separately;

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325797078&siteId=291194637