spring源码学习(一)

 2019-11-02 21:04  阅读(749)
文章分类:Spring boot

DefaultListableBeanFactory是bean加载的核心部分,是Spring注册和加载bean的默认实现。
DefaultListableBeanFactory的层次结构。
20191102100524\_1.png

自己画了个uml图如下:
20191102100524\_2.png

AliasRegistry接口:定义对alias的增删改查

SimpleAliasRegistry类:对AliasRegistry接口进行了实现,用map来存alias
20191102100524\_3.png

SingletonBeanRegistry接口:定义了单例的注册和获取

BeanFactory接口:定义了获取bean以及获取bean的各种属性

DefaultSingletonBeanRegistry类:对SingletonBeanRegistry接口进行了实现

HierarchicalBeanFactory接口:增加了对parentBean的支持。

BeanDefinitionRegistry:定义了对BeanDefinition的增删改查

FactoryBeanRegistrySupport:增加了对FactoryBeand的处理。

ConfigurableBeanFactory接口:提供了配置Factory的各种方法

ListableBeanFactory接口:根据各种条件获取bean的配置清单

AbstractBeanFactory类:综合了ListableBeanFactory和ConfigurableBeanFactory的功能

AutowireCapableBeanFactory接口:定义了bean的创建,自动注入,初始化以及应用bean后的处理

AbstractAutowireCapableBeanFactory类:对AutowireCapableBeanFactory接口进行实现,综合了AbstractBeanFactory和AutowireCapableBeanFactory的功能

ConfigurableListableBeanFactory接口:BeanFactory的配置清单

DefaultListableBeanFactory类:综合了全部功能

XmlBeanFactory继承DefaultListableBeanFactory,主要增加了通过xml文档来去读BeanDefinition,而注册和获取都是通过DefaulListableBeanFactory来实现的。
20191102100524\_4.png
XmlBeanFactory源码增加了XmlBeanDefinitionReader来读取Resource之后通过this.reader.loadBeanDefinitions来读取解析xml文档并注册。

因为XmlBeanFactory接受的参数是Resuorce类型的,所以要用new ClassPathResource来将目标文件转换为Resuorce类型。

接下来我进入loadBeanDefinitions方法,发现传入的Resource先被封装为了EncodedResource类,然后在另一个重载方法中获取对应的InputStrom并构造InputSource,然后将InputSource调用doLoadBeanDefinitions方法来进行解析。
在doLoadBeanDefinitions里将Resource转换为了Document,然后根据Document注册Bean信息。
20191102100524\_5.png
进入doLoadDocument方法里,我们能看到里面调用了getValidationModeForResource方法,这个方法是来验证xml是否符合dtd或者xsd中定义的格式的。
20191102100524\_6.png

到这里我们可以做一个小测试:
applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>  
    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">    

        <bean id="hello" class="springtest.MyTestBean"/>  
    </beans>

MyTestBean.java

public class MyTestBean {

        private String teststr = "hello world";

        public String getTeststr() {
            return teststr;
        }

        public void setTeststr(String teststr) {
            this.teststr = teststr;
        }

    }

BeanFactoryTest.java

import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;

    import org.springframework.beans.factory.xml.XmlBeanFactory;
    import org.springframework.core.io.ClassPathResource;

    public class BeanFactoryTest {

        public static void main(String[] args) throws IOException {
            XmlBeanFactory xmlBeanFactory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
            System.out.println("BeanFactory中Bean的数量:"+xmlBeanFactory.getBeanDefinitionCount());
            String[] bdNames = xmlBeanFactory.getBeanDefinitionNames();
            for(String str: bdNames)
                System.out.println("bean的名字:"+str);
            MyTestBean bean = (MyTestBean)xmlBeanFactory.getBean("hello");
            System.out.println(bean.getTeststr());
        }

    }

运行后的结果:
20191102100524\_7.png

如此简单的代码,在spring中其实是非常复杂的,上面分析的只是粗略的看了比较顶层的源码,接下来会继续分析更深层的代码。

上层代码的逻辑大概是:将文件转换为resource类型传入XmlBeanFactory中,XmlBeanFactory使用XmlBeanDefinitionReader中的loadBeanDefinitions来分析解析和注册bean,在loadBeanDefinitions中调用doLoadBeanDefinitions方法来验证资源文件并转换为Document类型,然后根据Document来进行Bean的解析和注册。

建议大家搭建环境,自己进去看看,不然很难弄清楚的。


来源:http://ddrv.cn

点赞(0)
版权归原创作者所有,任何形式转载请联系作者; Java 技术驿站 >> spring源码学习(一)

相关推荐