spring源码学习(一)

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

自己画了个uml图如下:
DefaultListableBeanFactory层次结构图

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

SimpleAliasRegistry类:对AliasRegistry接口进行了实现,用map来存alias
SimpleAliasRegistry

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来实现的。
XmlBeanFactory
XmlBeanFactory源码增加了XmlBeanDefinitionReader来读取Resource之后通过this.reader.loadBeanDefinitions来读取解析xml文档并注册。

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

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

到这里我们可以做一个小测试:
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());
    }

}

运行后的结果:
result

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

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值