Spring源码学习 一

本文介绍了Spring框架中的核心概念,如BeanDefinition和BeanDefinitionReader。BeanDefinition是Spring容器中对象的元数据,包含了对象创建所需的信息。XmlBeanDefinitionReader用于读取和解析XML配置文件,将BeanDefinition加载到Spring容器。文章详细阐述了BeanDefinition的接口和类结构,以及XmlBeanDefinitionReader的使用过程。
摘要由CSDN通过智能技术生成

 

 

 

什么是Spring呢?

 

我的理解是:Spring是一个容器。只不过这个容器设计的十分复制和巧妙。它外层是一个叫ApplicatContext的容器,内层存在一个叫BeanFactory的容器来管理bean的创建与管理。它向上可以连接视图层,展示页面,向下可以映射dao层操作数据。它通过Ioc和DI来管理程序的javaBean,实现MVC中的M和V的连接中介。

什么是Ioc/DI呢

Ioc/DI 就是 控制反转/依赖注入 。对象之间的关系交由Spring容器来管理。比如我们需要在A类中调用B类。以前的做法是在A类中直接 B b = new B()。

那么现在有了Spring之后这个过程就交由Spring管理。有Spring来管理什么时间创建B类,什么时间调用以及什么时间销毁。那么我们必须要创建这样一个容器吧,同时需要一种描述让容器知道我们程序的POJO类直接的关系,最直观的描述是通过配置文件来实现。

目前通用的主要是properties和xml等语义化配置文件。

描述对象关系的文件存放在哪里?

可能是 classpath , filesystem ,或者是 URL 网络资源, servletContext 等。

回到正题,有了配置文件,还需要对配置文件解析。

不同的配置文件对对象的描述不一样,如标准的,自定义声明式的,如何统一? 在内部需要有一个统一的关于对象的定义,所有外部的描述都必须转化成统一的描述定义。

如何对不同的配置文件进行解析?需要对不同的配置文件语法,采用不同的解析器

从上面可知:Ioc和DI肯定是spring中重要的模块。那么问题来了,它是如何被设计的呢?

一个POJO类,是如何被spring容器感知并自动纳入管理的呢?这个就需要从Spring如何感知POJO类开始。

一、Spring如何感知我们的POJO类

1、xml配置文件

Spring解析Xml配置需要用到dom4j。BeanDefinitionReader的设计用意是在启动Spring时加载BeanDefintion对象。Spring容器启动的过程中,会将Bean解析成Spring内部的BeanDefinition结构,每一个受管的对象,在容器中都会有一个BeanDefinition的实例与之相对应。该BeanDefinition的实例负责保存对象的所有必要信息,包括其对应的对象的class类型、是否是抽象类、构造方法参数以及其他属性。  BeanDefinition结构如下:

AttributeAccessor接口:

//元数据操作接口
public interface AttributeAccessor
{
    //设置元数据
    public abstract void setAttribute(String s, Object obj);
    //获取元数据
    public abstract Object getAttribute(String s);
    //删除元数据
    public abstract Object removeAttribute(String s);
    // 是否含有元数据
    public abstract boolean hasAttribute(String s);
    //获取元数据的name数组
    public abstract String[] attributeNames();
}

BeanMetadataElement接口:

//用于承载bean对象
public interface BeanMetadataElement
{
    //获取当前 元素的配置源bean对象
    public abstract Object getSource();
}

BeanDefinition接口:

//用于描述一个具体bean实例
public interface BeanDefinition
    extends AttributeAccessor, BeanMetadataElement
{
    //返回该bean定义的父bean定义的名称,如果有的话<bean parent=""/>
    public abstract String getParentName();
    public abstract void setParentName(String s);

    //获取bean对象的className  <bean class="">
    public abstract String getBeanClassName();
    public abstract void setBeanClassName(String s);

    //返回创建该bean对象的工厂类 <bean factory-bean="">
    public abstract String getFactoryBeanName();
    public abstract void setFactoryBeanName(String s);

    //返回创建该bean对象的工厂方法 <bean factory-method="">
    public abstract String getFactoryMethodName();
    public abstract void setFactoryMethodName(String s);

    //返回该bean的初始化方式:单例或者多例方式 默认单例模式 <bean scope="singletion/prototype"
    public abstract String getScope();
    public abstract void setScope(String s);

    //返回加载该bean的方式 默认懒加载 <bean lazy-init="true/false">
    public abstract boolean isLazyInit();
    public abstract void setLazyInit(boolean flag);

    //返回该bean的依赖对象 <bean depends-on="">
    public abstract String[] getDependsOn();
    public transient abstract void setDependsOn(String as[]);

    //是否为被自动装配 <bean autowire-candidate="true/false">
    public abstract boolean isAutowireCandidate();
    public abstract void setAutowireCandidate(boolean flag);

    //是否为主候选bean 使用注解 @Primary
    public abstract boolean isPrimary();
    public abstract void setPrimary(boolean flag);

    //返回此bean的构造函数参数值
    public abstract ConstructorArgumentValues getConstructorArgumentValues();
    //返回该bean的普通属性集合
    public abstract MutablePropertyValues getPropertyValues();

    //判断该bean是否为单利
    public abstract boolean isSingleton();
    //判断该bean是否为多例
    public abstract boolean isPrototype();

    //判断该bean是否为抽象方法
    public abstract boolean isAbstract();
    //获得这个bean的应用
    public abstract int getRole();

    //返回对该bean的描述 
    public abstract String getDescription();
    //返回该bean定义来自的资源的描述(用于在出现错误时显示上下文)
    public abstract String getResourceDescription();

    
    public abstract BeanDefinition getOriginatingBeanDefinition();
    //单例
    public static final String SCOPE_SINGLETON = "singleton";
    //多例
    public static final String SCOPE_PROTOTYPE = "prototype";
    //bean角色 用户
    public static final int ROLE_APPLICATION = 0;
    //某些复杂的配置
    public static final int ROLE_SUPPORT = 1;
    //完全内部使用
    public static final int ROLE_INFRASTRUCTURE = 2;
}

 AbstractBeanDefinition 抽象类:

//抽象类 基础bean
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
    implements BeanDefinition, Cloneable
{
    //空构造函数
    protected AbstractBeanDefinition()
    {
        this(null, null);
    }
    //知道的构造函数的参数值和属性值
    protected AbstractBeanDefinition(ConstructorArgumentValues cargs, MutablePropertyValues pvs)
    {
        scope = "";
        abstractFlag = false;
        lazyInit = false;
        autowireMode = 0;
        dependencyCheck = 0;
        autowireCandidate = true;
        primary = false;
        qualifiers = new LinkedHashMap(0);
        nonPublicAccessAllowed = true;
        lenientConstructorResolution = true;
        methodOverrides = new MethodOverrides();
        enforceInitMethod = true;
        enforceDestroyMethod = true;
        synthetic = false;
        role = 0;
        setConstructorArgumentValues(cargs);
        setPropertyValues(pvs);
    }
    //深拷贝构造
    protected AbstractBeanDefinition(BeanDefinition original)
    {
        scope = "";
        abstractFlag = false;
        lazyInit = false;
        autowireMode = 0;
        dependencyCheck = 0;
        autowireCandidate = true;
        primary = false;
        qualifiers = new LinkedHashMap(0);
        nonPublicAccessAllowed = true;
        lenientConstructorResolution = true;
        methodOverrides = new MethodOverrides();
        enforceInitMethod = true;
        enforceDestroyMethod = true;
        synthetic = false;
        role = 0;
        setParentName(original.getParentName());
        setBeanClassName(original.getBeanClassName());
        setFactoryBeanName(original.getFactoryBeanName());
        setFactoryMethodName(original.getFactoryMethodName());
        setScope(original.getScope());
        setAbstract(original.isAbstract());
        setLazyInit(original.isLazyInit());
        setRole(original.getRole());
        setConstructorArgumentValues(new ConstructorArgumentValues(original.getConstructorArgumentValues()));
        setPropertyValues(new MutablePropertyValues(original.getPropertyValues()));
        setSource(original.getSource());
        copyAttributesFrom(original);
        if(original instanceof AbstractBeanDefinition)
        {
            AbstractBeanDefinition originalAbd = (AbstractBeanDefinition)original;
            if(originalAbd.hasBeanClass())
                setBeanClass(originalAbd.getBeanClass());
            setAutowireMode(originalAbd.getAutowireMode());
            setDependencyCheck(originalAbd.getDependencyCheck());
            setDependsOn(originalAbd.getDependsOn());
            setAutowireCandidate(originalAbd.isAutowireCandidate());
            copyQualifiersFrom(originalAbd);
            setPrimary(originalAbd.isPrimary());
            setNonPublicAccessAllowed(originalAbd.isNonPublicAccessAllowed());
            setLenientConstructorResolution(originalAbd.isLenientConstructorResolution());
            setInitMethodName(originalAbd.getInitMethodName());
            setEnforceInitMethod(originalAbd.isEnforceInitMethod());
            setDestroyMethodName(originalAbd.getDestroyMethodName());
            setEnforceDestroyMethod(originalAbd.isEnforceDestroyMethod());
            setMethodOverrides(new MethodOverrides(originalAbd.getMethodOverrides()));
            setSynthetic(originalAbd.isSynthetic());
            setResource(originalAbd.getResource());
        } else
        {
            setResourceDescription(original.getResourceDescription());
        }
    }
    // 从给定的bean定义(大概是子)中覆盖此bean定义(可能是来自父子继承关系的复制父)的设置。
    public void overrideFrom(BeanDefinition other)
    {
        if(StringUtils.hasLength(other.getBe
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于学习Spring源码的网站,可以参考以下链接: 1. Spring官方网站:https://spring.io/ 在官方网站上,你可以找到关于Spring的所有文档、教程和源码下载链接。它是学习Spring的首要资源。 2. GitHub上的Spring源码仓库:https://github.com/spring-projects/spring-framework 这是Spring源码的官方GitHub仓库,你可以在这里找到最新的Spring源码,并参与到开发讨论中。 3. CSDN博客:https://blog.csdn.net/navyfrost/article/details/102919323 这是一篇关于Spring源码学习的博客文章,作者分享了学习Spring源码的心得和方法,并提供了一些学习资源和案例。 希望以上资源可以帮助你开始学习Spring源码。祝你学习顺利!<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span> #### 引用[.reference_title] - *1* [Spring源码学习加注释,方便学习.zip](https://download.csdn.net/download/weixin_47367099/85350853)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* *4* [Spring源码学习系列——源码下载和环境](https://blog.csdn.net/shangguoli/article/details/124710529)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值