spring源码解析(3)-BeanDefinition

BeanDefinition是一个接口,代表XML文档中<bean>元素的类表现形式,它有三个子类RootBeanDefinition,ChildBeanDefinition和GenericBeanDefinition。

对<bean>元素的实际解析主要通过XmlBeanDefinitionReader、DefaultBeanDefinitionDocumentReader、BeanDefinitionParserDelegate这三个类
主要用到了BeanDefinitionParserDelegate中的三个方法
复制代码
(1)public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) 
//方法解析了id、name两个标签,并把其他标签交给另一个parseBeanDefinitionElement来处理
(2)public AbstractBeanDefinition parseBeanDefinitionElement( Element ele, String beanName, 
@Nullable BeanDefinition containingBean)
//方法解析了class、parent两个标签,并把其他标签交给了下一个方法parseBeanDefinitionAttributes
(3)public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, 
String beanName,@Nullable BeanDefinition containingBean, AbstractBeanDefinition bd)
//方法对bean元素的剩下的各种标签进行了解析,包括scope、singleton、abstract、lazy-init、autowire、dependency-check、depends-on、primary、init-method、destroy-method、factory-method等
//并将解析得到的信息存储到AbstractBeanDefinition抽象类中,这个类也实现了BeanDefinition接口。
复制代码

 



另外贴一下方法的源码,因为它除了解析了<bean>的一级标签外,在后面的调用中还解析了<meta><lookup-method><replaced-method><constructor-arg><property>
<qualifier>等子标签,非常重要。
复制代码
public AbstractBeanDefinition parseBeanDefinitionElement(
            Element ele, String beanName, @Nullable BeanDefinition containingBean) {

        this.parseState.push(new BeanEntry(beanName));

        String className = null;
        if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
            className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
        }
        String parent = null;
        if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
            parent = ele.getAttribute(PARENT_ATTRIBUTE);
        }

        try {
            AbstractBeanDefinition bd = createBeanDefinition(className, parent);

            parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
            bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));

            parseMetaElements(ele, bd);
            parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
            parseReplacedMethodSubElements(ele, bd.getMethodOverrides());

            parseConstructorArgElements(ele, bd);
            parsePropertyElements(ele, bd);
            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;
    }
复制代码

 想要了解解析后的到底拿到了哪些属性,可以看一下AbstractBeanDefinition类

posted @   Mars.wang  阅读(54)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗
点击右上角即可分享
微信分享提示