1. 准备

启动类

public class FileSystemXmlApplicationContextStartProcess {

    public static void main(String[] args){

        FileSystemXmlApplicationContext cxt = new FileSystemXmlApplicationContext("bean.xml");

        User user = (User)cxt.getBean("user");

        System.out.println(user);

    }

}

bean.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"

       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

       <bean id="user" class="domain.User"></bean>

</beans>

2. 开始分析

FileSystemXmlApplicationContext构造方法

public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException {

    super(parent);

    this.setConfigLocations(configLocations);

    if (refresh) {

        //这里调用容器的refresh,是载入BeanDefinition的入口

        this.refresh();

    }

}

AbstractApplicationContext.refresh

public void refresh() throws BeansException, IllegalStateException {

    Object var1 = this.startupShutdownMonitor;

    synchronized(this.startupShutdownMonitor) {

        this.prepareRefresh();

        //这里是在子类中启动refreshBeanFactory()的地方

        ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();

        this.prepareBeanFactory(beanFactory);

 

        try {

            //设置BeanFactory的后置处理

            this.postProcessBeanFactory(beanFactory);

            //调用BeanFactory的后处理器,这些后处理器是在Bean定义中向容器注册的

            this.invokeBeanFactoryPostProcessors(beanFactory);

            //注册Bean的后处理器,在Bean创建过程中调用

            this.registerBeanPostProcessors(beanFactory);

            //对上下文中的消息源进行初始化

            this.initMessageSource();

            //初始化上下文中的事件机制

            this.initApplicationEventMulticaster();

            //初始化其他特殊Bean

            this.onRefresh();

            //检查监听Bean并且将这些Bean向容器注册

            this.registerListeners();

            //实例化所有的(no-lazy-init)单件

            this.finishBeanFactoryInitialization(beanFactory);

            //发布容器事件,结束Refresh过程

            this.finishRefresh();

        catch (BeansException var5) {

            //防止Bean资源占有,出异常的时候,销毁前面生成的Bean

            this.destroyBeans();

            //重置active标志

            this.cancelRefresh(var5);

            throw var5;

        }

 

    }

}

AbstractRefreshableApplicationContext.refreshBeanFactory

protected final void refreshBeanFactory() throws BeansException {

    if (this.hasBeanFactory()) {

        this.destroyBeans();

        this.closeBeanFactory();

    }

 

    try {

        //创建IoC容器,这里使用的是DefaultListableBeanFactory

        DefaultListableBeanFactory beanFactory = this.createBeanFactory();

        beanFactory.setSerializationId(this.getId());

        this.customizeBeanFactory(beanFactory);

        //启动对BeanDefintion的载入

        this.loadBeanDefinitions(beanFactory);

        Object var2 = this.beanFactoryMonitor;

        synchronized(this.beanFactoryMonitor) {

            this.beanFactory = beanFactory;

        }

    catch (IOException var5) {

        throw new ApplicationContextException("I/O error parsing bean definition source for " this.getDisplayName(), var5);

    }

}

AbstractXmlApplicationContext.loadBeanDefinitions

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {

    //创建XmlBeanDefinitionReader,通过回调设置BeanFactory中去

    XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

    beanDefinitionReader.setEnvironment(this.getEnvironment());

    //这里设置好XmlBeanDefinitionReader,为XmlBeanDefinitionReader配置ResourceLoader,因为DefaultResourceLoader是父类,所以this可以直接使用

    beanDefinitionReader.setResourceLoader(this);

    beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

    //这里是启动Bean定义信息载入过程

    this.initBeanDefinitionReader(beanDefinitionReader);

    this.loadBeanDefinitions(beanDefinitionReader);

}

AbstractXmlApplicationContext.loadBeanDefinitions

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {

    //以Resource的方式获得配置文件的资源位置  第一步获取到位置

    Resource[] configResources = this.getConfigResources();

    if (configResources != null) {

        reader.loadBeanDefinitions(configResources);

    }

    //以String的形式获取配置文件的位置

    String[] configLocations = this.getConfigLocations();

    if (configLocations != null) {

        reader.loadBeanDefinitions(configLocations);

    }

}

AbstractBeanDefinitionReader.loadBeanDefinitions

public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {

    //如果Resource为空,则停止BeanDefinition的载入

    Assert.notNull(resources, "Resource array must not be null");

    int counter = 0;

    Resource[] var3 = resources;

    int var4 = resources.length;

    //遍历整个Resource集合所包含的BeanDefinition信息

    for(int var5 = 0; var5 < var4; ++var5) {

        Resource resource = var3[var5];

        //这个方法在AbstractBeanDefinitionReader,这是一个接口,没有实现具体使用的是xmlBeanDefinitionReader中

        counter += this.loadBeanDefinitions((Resource)resource);

    }

    return counter;

}

XmlBeanDefinitionReader.loadBeanDefinitions

//调用入口

public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {

    return this.loadBeanDefinitions(new EncodedResource(resource));

}

//这里是载入XML形式的BeanDefinition的地方

public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {

    Assert.notNull(encodedResource, "EncodedResource must not be null");

    if (this.logger.isInfoEnabled()) {

        this.logger.info("Loading XML bean definitions from " + encodedResource.getResource());

    }

 

    Set<EncodedResource> currentResources = (Set)this.resourcesCurrentlyBeingLoaded.get();

    if (currentResources == null) {

        currentResources = new HashSet(4);

        this.resourcesCurrentlyBeingLoaded.set(currentResources);

    }

 

    if (!((Set)currentResources).add(encodedResource)) {

        throw new BeanDefinitionStoreException("Detected cyclic loading of " + encodedResource + " - check your import definitions!");

    else {

        int var5;

        try {

            //这里得到XML文件,并且得到IO的InputSource准备进行读取

            InputStream inputStream = encodedResource.getResource().getInputStream();

            try {

                InputSource inputSource = new InputSource(inputStream);

                if (encodedResource.getEncoding() != null) {

                    inputSource.setEncoding(encodedResource.getEncoding());

                }

                var5 = this.doLoadBeanDefinitions(inputSource, encodedResource.getResource());

            finally {

                inputStream.close();

            }

        catch (IOException var15) {

            throw new BeanDefinitionStoreException("IOException parsing XML document from " + encodedResource.getResource(), var15);

        finally {

            ((Set)currentResources).remove(encodedResource);

            if (((Set)currentResources).isEmpty()) {

                this.resourcesCurrentlyBeingLoaded.remove();

            }

 

        }

        return var5;

    }

}

XmlBeanDefinitionReader.doLoadBeanDefinitons

//具体的读取过程可以在doLoadBeanDefinition方法中找到,这是从特定的XML文件中实际载入BeanDefinition的地方

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {

    try {

        //这里取得XML文件的Document对象,这里完成的是对XML的通用解析

        Document doc = this.doLoadDocument(inputSource, resource);

        //这里启动是对BeanDefinition解析的详细过程,这个解析会使用到Spring的Bean配置规则

        return this.registerBeanDefinitions(doc, resource);

    catch (BeanDefinitionStoreException var4) {

        throw var4;

    catch (SAXParseException var5) {

        throw new XmlBeanDefinitionStoreException(resource.getDescription(), "Line " + var5.getLineNumber() + " in XML document from " + resource + " is invalid", var5);

    catch (SAXException var6) {

        throw new XmlBeanDefinitionStoreException(resource.getDescription(), "XML document from " + resource + " is invalid", var6);

    catch (ParserConfigurationException var7) {

        throw new BeanDefinitionStoreException(resource.getDescription(), "Parser configuration exception parsing XML from " + resource, var7);

    catch (IOException var8) {

        throw new BeanDefinitionStoreException(resource.getDescription(), "IOException parsing XML document from " + resource, var8);

    catch (Throwable var9) {

        throw new BeanDefinitionStoreException(resource.getDescription(), "Unexpected exception parsing XML document from " + resource, var9);

    }

}

 

 

protected Document doLoadDocument(InputSource inputSource, Resource resource) throws Exception {

    //这个documentloader是DefaultDocumentLoader

    return this.documentLoader.loadDocument(inputSource, this.getEntityResolver(), this.errorHandler, this.getValidationModeForResource(resource),      this.isNamespaceAware());

}

XmlBeanDefinitionReader.registerBeanDefinitions

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {

    //这里得到BeanDefinitionDocumentReader来对XML的BeanDefinition进行解析

    BeanDefinitionDocumentReader documentReader = this.createBeanDefinitionDocumentReader();

    documentReader.setEnvironment(this.getEnvironment());

    int countBefore = this.getRegistry().getBeanDefinitionCount();

    //具体解析过程在这里,这里是按Spring的Bean规则解析

    documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource));

    return this.getRegistry().getBeanDefinitionCount() - countBefore;

}

DefaultBeanDefinitionDocumentReader.registerBeanDefinitions

public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {

    this.readerContext = readerContext;

    this.logger.debug("Loading bean definitions");

    //得到root节点,也就是beans

    Element root = doc.getDocumentElement();

    //解析和注册都在这里,目前关注解析

    this.doRegisterBeanDefinitions(root);

}

DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions

protected void doRegisterBeanDefinitions(Element root) {

    String profileSpec = root.getAttribute("profile");

    if (StringUtils.hasText(profileSpec)) {

        Assert.state(this.environment != null"Environment must be set for evaluating profiles");

        String[] specifiedProfiles = StringUtils.tokenizeToStringArray(profileSpec, ",; ");

        if (!this.environment.acceptsProfiles(specifiedProfiles)) {

            return;

        }

    }

 

    BeanDefinitionParserDelegate parent = this.delegate;

    this.delegate = this.createDelegate(this.readerContext, root, parent);

    this.preProcessXml(root);

    //解析Bean的入口,BeanDefinitionParserDelegate这个对象是用来解析dom结构的

    this.parseBeanDefinitions(root, this.delegate);

    this.postProcessXml(root);

    this.delegate = parent;

}

DefaultBeanDefinitionDocumentReader.parseBeanDefinitions

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {

    if (delegate.isDefaultNamespace(root)) {

        NodeList nl = root.getChildNodes();

 

        for(int i = 0; i < nl.getLength(); ++i) {

            Node node = nl.item(i);

            if (node instanceof Element) {

                Element ele = (Element)node;

                if (delegate.isDefaultNamespace(ele)) {

                    //举个一般例子,一般解析默认的bean元素进这里,这个有个参数是delegate,其实就是这个对象使用ele元素完成解析功能

                    this.parseDefaultElement(ele, delegate);

                else {

                    delegate.parseCustomElement(ele);

                }

            }

        }

    else {

        delegate.parseCustomElement(root);

    }

 

}

DefaultBeanDefinitionDocumentReader.parseDefaultElement

private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {

    if (delegate.nodeNameEquals(ele, "import")) {

        this.importBeanDefinitionResource(ele);

    else if (delegate.nodeNameEquals(ele, "alias")) {

        this.processAliasRegistration(ele);

    else if (delegate.nodeNameEquals(ele, "bean")) {

        //bean的解析入口

        this.processBeanDefinition(ele, delegate);

    else if (delegate.nodeNameEquals(ele, "beans")) {

        this.doRegisterBeanDefinitions(ele);

    }

}

DefaultBeanDefinitionDocumentReader.processBeanDefinition

//这里是处理BeanDefinition的地方,具体委托给BeanDefinitionParserDelegate完成,ele对应XML元素,DOM树元素

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {

    //BeanDefinitionHolder是BeanDefiniton对象的封装类,封装类BeanDefinition,Bean的名字和别名,用它完成向Ioc容器注册

    //得到这个BeanDefinitionHolder就说明BeanDefinition是通过BeanDefinitionParserDelegate对XML元素按SpringBean的规则解析得到

    //这里只关注解析,方法进入这里

    BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);

    if (bdHolder != null) {

        bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);

 

        try {

            //这里向IoC容器注册BeanDefinition

            BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry());

        catch (BeanDefinitionStoreException var5) {

            this.getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, var5);

        }

        //在BeanDefinition向IoC容器注册完以后,发送消息

        this.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));

    }

 

}

BeanDefintionParserDelegate.parseBeanDefinitionElement

//对外接口

public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {

    return this.parseBeanDefinitionElement(ele, (BeanDefinition)null);

}

//真实方法实现

public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {

    //这里获取bean元素的id,name,aliase属性的值

    String id = ele.getAttribute("id");

    String nameAttr = ele.getAttribute("name");

    List<String> aliases = new ArrayList();

    if (StringUtils.hasLength(nameAttr)) {

        String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, ",; ");

        aliases.addAll(Arrays.asList(nameArr));

    }

 

    String beanName = id;

    if (!StringUtils.hasText(id) && !aliases.isEmpty()) {

        beanName = (String)aliases.remove(0);

        if (this.logger.isDebugEnabled()) {

            this.logger.debug("No XML 'id' specified - using '" + beanName + "' as bean name and " + aliases + " as aliases");

        }

    }

 

    if (containingBean == null) {

        this.checkNameUniqueness(beanName, aliases, ele);

    }

    //这个方法会引发对Bean元素的解析,这里是得到BeanDefinition的地方

    AbstractBeanDefinition beanDefinition = this.parseBeanDefinitionElement(ele, beanName, containingBean);

    if (beanDefinition != null) {

        if (!StringUtils.hasText(beanName)) {

            try {

                if (containingBean != null) {

                    beanName = BeanDefinitionReaderUtils.generateBeanName(beanDefinition, this.readerContext.getRegistry(), true);

                else {

                    beanName = this.readerContext.generateBeanName(beanDefinition);

                    //解析className

                    String beanClassName = beanDefinition.getBeanClassName();

                    if (beanClassName != null && beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() && !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {

                        aliases.add(beanClassName);

                    }

                }

 

                if (this.logger.isDebugEnabled()) {

                    this.logger.debug("Neither XML 'id' nor 'name' specified - using generated bean name [" + beanName + "]");

                }

            catch (Exception var9) {

                this.error(var9.getMessage(), ele);

                return null;

            }

        }

 

        String[] aliasesArray = StringUtils.toStringArray(aliases);

        //这里是返回BeanDefinitionHolder的地方,从这里也能看出,这个对象中含有BeanDefintion,beanName,和别名

        return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);

    else {

        return null;

    }

}

这里的解析一般都是按XML定义元素来解析的,可以和XML元素对应起来

BeanDefinitionParserDelegate.parseBeanDefinitionElement

public AbstractBeanDefinition parseBeanDefinitionElement(Element ele, String beanName, BeanDefinition containingBean) {

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

    //这里只读取Bean中定义的class名字,然后载入BeanDefinition中去,只是记录,不实例化,实例化是依赖注入的过程

    String className = null;

    if (ele.hasAttribute("class")) {

        className = ele.getAttribute("class").trim();

    }

 

    try {

        String parent = null;

        if (ele.hasAttribute("parent")) {

            parent = ele.getAttribute("parent");

        }

        //这里生成BeanDefinition对象,为Bean定义信息载入做准备

        AbstractBeanDefinition bd = this.createBeanDefinition(className, parent);

        //这里对当前的Bean元素进行属性解析,并设置description的信息

        this.parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);

        bd.setDescription(DomUtils.getChildElementValueByTagName(ele, "description"));

        //设置各种bean元素中的子元素的地方

        this.parseMetaElements(ele, bd);

        this.parseLookupOverrideSubElements(ele, bd.getMethodOverrides());

        this.parseReplacedMethodSubElements(ele, bd.getMethodOverrides());

        //解析构造函数

        this.parseConstructorArgElements(ele, bd);

        //解析property设置

        this.parsePropertyElements(ele, bd);

        this.parseQualifierElements(ele, bd);

        bd.setResource(this.readerContext.getResource());

        bd.setSource(this.extractSource(ele));

        AbstractBeanDefinition var7 = bd;

        return var7;

    //下面这些异常是在配置Bean出现问题时经常会看到的,原来是在这里抛出这些检查是在createBeanDefinition时进行的,会检查Bean的class设置是否正确

    catch (ClassNotFoundException var13) {

        this.error("Bean class [" + className + "] not found", ele, var13);

    catch (NoClassDefFoundError var14) {

        this.error("Class that bean class [" + className + "] depends on not found", ele, var14);

    catch (Throwable var15) {

        this.error("Unexpected failure during bean definition parsing", ele, var15);

    finally {

        this.parseState.pop();

    }

 

    return null;

}

具体的解析property等等属性就不继续往下追了,剩下就是具体解析了,一些propertyvalue,list,set解析的方法

 

3. 流程图分析

 

4. 总结

将静态的数据例如xml,转化为动态的数据结构BeanDefinition,如何载入,并且按spring的规则解析