zoukankan      html  css  js  c++  java
  • Spring5源码分析(014)——IoC篇之解析bean标签:解析各种属性

    注:《Spring5源码分析》汇总可参考:Spring5源码分析(002)——博客汇总


      前面的篇章提到, parseBeanDefinitionElement( Element ele, String beanName, @Nullable BeanDefinition containingBean) 方法内部就是对 bean 标签的各种属性和子元素的解析,然后封装到 AbstractBeanDefinition 中。本文将对解析 bean 标签的各种属性这一步进行分析,这里调用的是 BeanDefinitionParserDelegate.parseBeanDefinitionAttributes(Element ele, String beanName,@Nullable BeanDefinition containingBean, AbstractBeanDefinition bd) 方法进行属性的解析,没有什么特殊处理处理,基本上就是去读给定 bean 标签的各种指定的属性,然后设置到 AbstractBeanDefinition 实例中。

    /**
     * Apply the attributes of the given bean element to the given bean * definition.
     * <p>解析给定 bean 元素的属性然后设置到 bean 定义中
     * @param ele bean declaration element
     * @param beanName bean name
     * @param containingBean containing bean definition
     * @return a bean definition initialized according to the bean element attributes
     */
    public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName,
            @Nullable BeanDefinition containingBean, AbstractBeanDefinition bd) {
    
        // 解析 singleton 属性
        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));
        }
        else if (containingBean != null) {
            // Take default from containing bean in case of an inner bean definition.
            // 如果都没有设置,则使用嵌入 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 (isDefaultValue(lazyInit)) {
            lazyInit = this.defaults.getLazyInit();
        }
        bd.setLazyInit(TRUE_VALUE.equals(lazyInit));
    
        // 解析 autowire 属性
        String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);
        bd.setAutowireMode(getAutowireMode(autowire));
    
        // 解析 depends-on 属性
        if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {
            String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);
            bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, MULTI_VALUE_ATTRIBUTE_DELIMITERS));
        }
    
        // 解析 autowire-candidate 属性
        String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE);
        if (isDefaultValue(autowireCandidate)) {
            String candidatePattern = this.defaults.getAutowireCandidates();
            if (candidatePattern != null) {
                String[] patterns = StringUtils.commaDelimitedListToStringArray(candidatePattern);
                bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns, beanName));
            }
        }
        else {
            bd.setAutowireCandidate(TRUE_VALUE.equals(autowireCandidate));
        }
    
        // 解析 primary 属性
        if (ele.hasAttribute(PRIMARY_ATTRIBUTE)) {
            bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE)));
        }
    
        // 解析 init-method 属性
        if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) {
            String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE);
            bd.setInitMethodName(initMethodName);
        }
        else if (this.defaults.getInitMethod() != null) {
            bd.setInitMethodName(this.defaults.getInitMethod());
            bd.setEnforceInitMethod(false);
        }
    
        // 解析 destroy-method 属性
        if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE)) {
            String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE);
            bd.setDestroyMethodName(destroyMethodName);
        }
        else if (this.defaults.getDestroyMethod() != null) {
            bd.setDestroyMethodName(this.defaults.getDestroyMethod());
            bd.setEnforceDestroyMethod(false);
        }
    
        // 解析 factory-method 属性
        if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) {
            bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE));
        }
        // 解析 factory-bean 属性
        if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) {
            bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE));
        }
    
        return bd;
    }

      这里,我们可以清楚地看到 Spring 完成了对 bean 标签所有属性的解析,这些属性中有很多事是我们经常使用到或者见过的,例如 lazy-init 、 autowire 、 depends-on 、 init-method 、 destroy-method 、 factory-method 等,还有一些不太熟悉或者没有使用过的,如有兴趣可查阅相关资料进行进一步的了解,此不赘述。接下来的文章将对 bean 标签的子元素解析进行分析。

    参考

  • 相关阅读:
    ​Docker 数据卷的管理及自动构建docker镜像
    写代码有这16个好习惯,可以减少80%非业务的bug
    启动Docker“Got permission denied while trying to connect to the Docker daemon socket“问题(亲测可用)
    Docker从入门到干活,看这一篇足矣 [建议收藏]
    docker技术入门与精通(2020.12笔记总结)
    MySQL相关 死锁的发生和避免
    使用docker运行zabbixserver
    Cloudflare 是谁?
    扛得住的MySQL数据库架构
    好未来第一届PHP开源技术大会资料分享
  • 原文地址:https://www.cnblogs.com/wpbxin/p/13550964.html
Copyright © 2011-2022 走看看