Spring源码解析容器初始化构造的方法是什么

发布时间:2022-07-07 13:58:55 作者:iii
来源:亿速云 阅读:158

Spring源码解析容器初始化构造的方法是什么

引言

Spring框架作为Java开发中最流行的轻量级容器之一,其核心功能之一就是依赖注入(DI)和面向切面编程(AOP)。Spring容器的初始化是Spring框架启动的关键步骤,理解Spring容器的初始化过程对于深入掌握Spring框架的工作原理至关重要。本文将详细解析Spring容器初始化的构造方法,从源码层面剖析Spring容器是如何一步步完成初始化的。

1. Spring容器概述

1.1 Spring容器的基本概念

Spring容器是Spring框架的核心,负责管理应用中所有Bean的生命周期、依赖关系以及配置。Spring容器通过读取配置文件或注解来创建和管理Bean实例,并提供依赖注入、AOP等功能。

1.2 Spring容器的类型

Spring容器主要有两种类型:

在本文中,我们将主要关注ApplicationContext的初始化过程。

2. Spring容器初始化的基本流程

Spring容器的初始化过程可以分为以下几个主要步骤:

  1. 加载配置文件:读取Spring配置文件(如XML文件)或注解配置。
  2. 解析配置文件:将配置文件中的内容解析为Spring内部的表示形式。
  3. 注册Bean定义:将解析后的Bean定义注册到Spring容器中。
  4. 实例化Bean:根据Bean定义创建Bean实例。
  5. 依赖注入:将Bean之间的依赖关系注入到相应的Bean实例中。
  6. 初始化Bean:调用Bean的初始化方法(如init-method@PostConstruct注解)。
  7. 完成容器初始化:容器初始化完成,应用可以正常使用。

接下来,我们将详细解析每个步骤的源码实现。

3. 加载配置文件

Spring容器的初始化通常从加载配置文件开始。Spring支持多种配置方式,包括XML配置、Java配置和注解配置。我们以XML配置为例,解析Spring容器如何加载配置文件。

3.1 配置文件加载的入口

Spring容器初始化的入口通常是ClassPathXmlApplicationContextFileSystemXmlApplicationContext。这两个类都继承自AbstractApplicationContext,并实现了ConfigurableApplicationContext接口。

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

ClassPathXmlApplicationContext的构造函数中,会调用refresh()方法来完成容器的初始化。

public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
    this(new String[] {configLocation}, true, null);
}

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
        throws BeansException {
    super(parent);
    setConfigLocations(configLocations);
    if (refresh) {
        refresh();
    }
}

3.2 配置文件加载的实现

refresh()方法是Spring容器初始化的核心方法,它定义在AbstractApplicationContext类中。refresh()方法的主要作用是刷新Spring容器,重新加载配置文件并初始化Bean。

@Override
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // 准备刷新上下文
        prepareRefresh();

        // 告诉子类刷新内部的Bean工厂
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // 准备Bean工厂以供在此上下文中使用
        prepareBeanFactory(beanFactory);

        try {
            // 允许在上下文子类中对Bean工厂进行后处理
            postProcessBeanFactory(beanFactory);

            // 调用在上下文中注册为Bean的工厂处理器
            invokeBeanFactoryPostProcessors(beanFactory);

            // 注册拦截Bean创建的Bean处理器
            registerBeanPostProcessors(beanFactory);

            // 初始化消息源
            initMessageSource();

            // 初始化事件广播器
            initApplicationEventMulticaster();

            // 在特定上下文子类中初始化其他特殊Bean
            onRefresh();

            // 检查并注册监听器
            registerListeners();

            // 实例化所有剩余的(非懒加载的)单例Bean
            finishBeanFactoryInitialization(beanFactory);

            // 完成刷新过程,发布相应的事件
            finishRefresh();
        } catch (BeansException ex) {
            // 销毁已经创建的单例以避免资源泄漏
            destroyBeans();

            // 重置'active'标志
            cancelRefresh(ex);

            // 抛出异常
            throw ex;
        } finally {
            // 重置Spring核心中的常见内省缓存,因为我们可能不再需要单例Bean的元数据
            resetCommonCaches();
        }
    }
}

refresh()方法中,obtainFreshBeanFactory()方法负责加载和解析配置文件,并创建BeanFactory

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    refreshBeanFactory();
    return getBeanFactory();
}

refreshBeanFactory()方法在AbstractRefreshableApplicationContext类中实现,它会创建一个新的DefaultListableBeanFactory实例,并加载Bean定义。

@Override
protected final void refreshBeanFactory() throws BeansException {
    if (hasBeanFactory()) {
        destroyBeans();
        closeBeanFactory();
    }
    try {
        DefaultListableBeanFactory beanFactory = createBeanFactory();
        beanFactory.setSerializationId(getId());
        customizeBeanFactory(beanFactory);
        loadBeanDefinitions(beanFactory);
        this.beanFactory = beanFactory;
    } catch (IOException ex) {
        throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
    }
}

loadBeanDefinitions()方法负责加载Bean定义,具体的加载逻辑由XmlBeanDefinitionReader类实现。

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
    // 为给定的Bean工厂创建一个新的XmlBeanDefinitionReader
    XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

    // 配置Bean定义读取器
    beanDefinitionReader.setEnvironment(getEnvironment());
    beanDefinitionReader.setResourceLoader(this);
    beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

    // 允许子类提供自定义的初始化
    initBeanDefinitionReader(beanDefinitionReader);

    // 实际加载Bean定义
    loadBeanDefinitions(beanDefinitionReader);
}

loadBeanDefinitions()方法最终会调用XmlBeanDefinitionReaderloadBeanDefinitions()方法,该方法会解析XML配置文件并注册Bean定义。

public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
    return loadBeanDefinitions(new EncodedResource(resource));
}

public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
    // 省略部分代码...
    InputStream inputStream = encodedResource.getResource().getInputStream();
    InputSource inputSource = new InputSource(inputStream);
    return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
}

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {
    // 省略部分代码...
    Document doc = doLoadDocument(inputSource, resource);
    return registerBeanDefinitions(doc, resource);
}

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
    BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
    int countBefore = getRegistry().getBeanDefinitionCount();
    documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
    return getRegistry().getBeanDefinitionCount() - countBefore;
}

registerBeanDefinitions()方法中,DefaultBeanDefinitionDocumentReader类负责解析XML文档并注册Bean定义。

@Override
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
    this.readerContext = readerContext;
    Element root = doc.getDocumentElement();
    doRegisterBeanDefinitions(root);
}

protected void doRegisterBeanDefinitions(Element root) {
    BeanDefinitionParserDelegate parent = this.delegate;
    this.delegate = createDelegate(getReaderContext(), root, parent);

    // 解析前处理
    preProcessXml(root);
    parseBeanDefinitions(root, this.delegate);
    // 解析后处理
    postProcessXml(root);

    this.delegate = parent;
}

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)) {
                    parseDefaultElement(ele, delegate);
                } else {
                    delegate.parseCustomElement(ele);
                }
            }
        }
    } else {
        delegate.parseCustomElement(root);
    }
}

parseDefaultElement()方法中,Spring会根据XML元素的名称来解析不同的Bean定义。

private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
    if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
        importBeanDefinitionResource(ele);
    } else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
        processAliasRegistration(ele);
    } else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
        processBeanDefinition(ele, delegate);
    } else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
        // 递归处理嵌套的beans元素
        doRegisterBeanDefinitions(ele);
    }
}

processBeanDefinition()方法负责解析<bean>元素,并将其转换为BeanDefinition对象。

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
    BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
    if (bdHolder != null) {
        bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
        try {
            // 注册最终的Bean定义
            BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
        } catch (BeanDefinitionStoreException ex) {
            getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, ex);
        }
        // 发送注册事件
        getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
    }
}

parseBeanDefinitionElement()方法会将XML元素解析为BeanDefinition对象。

public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
    // 解析id和name属性
    String id = ele.getAttribute(ID_ATTRIBUTE);
    String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);

    // 解析别名
    List<String> aliases = new ArrayList<>();
    if (StringUtils.hasLength(nameAttr)) {
        String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, BEAN_NAME_DELIMITERS);
        aliases.addAll(Arrays.asList(nameArr));
    }

    String beanName = id;
    if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
        beanName = aliases.remove(0);
    }

    // 检查Bean名称的唯一性
    if (containingBean == null) {
        checkNameUniqueness(beanName, aliases, ele);
    }

    // 解析Bean定义
    AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
    if (beanDefinition != null) {
        if (!StringUtils.hasText(beanName)) {
            beanName = generateBeanName(beanDefinition, this.readerContext.getRegistry(), containingBean);
        }
        String[] aliasesArray = StringUtils.toStringArray(aliases);
        return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
    }

    return null;
}

parseBeanDefinitionElement()方法会进一步解析Bean的属性、构造函数参数、依赖关系等。

public AbstractBeanDefinition parseBeanDefinitionElement(Element ele, String beanName, BeanDefinition containingBean) {
    // 省略部分代码...
    AbstractBeanDefinition bd = createBeanDefinition(className, parent);

    parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
    parseConstructorArgElements(ele, bd);
    parsePropertyElements(ele, bd);
    parseQualifierElements(ele, bd);

    bd.setResource(this.readerContext.getResource());
    bd.setSource(extractSource(ele));

    return bd;
}

parseBeanDefinitionAttributes()方法会解析Bean的属性,如scopelazy-initdepends-on等。

public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName, BeanDefinition containingBean, AbstractBeanDefinition bd) {
    // 解析scope属性
    if (ele.hasAttribute(SCOPE_ATTRIBUTE)) {
        bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));
    } else if (containingBean != null) {
        bd.setScope(containingBean.getScope());
    }

    // 解析abstract属性
    if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) {
        bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE)));
    }

    // 解析lazy-init属性
    if (ele.hasAttribute(LAZY_INIT_ATTRIBUTE)) {
        bd.setLazyInit(TRUE_VALUE.equals(ele.getAttribute(LAZY_INIT_ATTRIBUTE)));
    }

    // 解析autowire属性
    if (ele.hasAttribute(AUTOWIRE_ATTRIBUTE)) {
        String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);
        bd.setAutowireMode(getAutowireMode(autowire));
    }

    // 解析depends-on属性
    if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {
        String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);
        bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, BEAN_NAME_DELIMITERS));
    }

    // 解析autowire-candidate属性
    if (ele.hasAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE)) {
        bd.setAutowireCandidate(TRUE_VALUE.equals(ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE)));
    }

    // 解析primary属性
    if (ele.hasAttribute(PRIMARY_ATTRIBUTE)) {
        bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE)));
    }

    // 解析init-method属性
    if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) {
        bd.setInitMethodName(ele.getAttribute(INIT_METHOD_ATTRIBUTE));
    }

    // 解析destroy-method属性
    if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE)) {
        bd.setDestroyMethodName(ele.getAttribute(DESTROY_METHOD_ATTRIBUTE));
    }

    // 解析factory-method属性
    if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) {
        bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE));
    }

    // 解析factory-bean属性
    if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) {
        bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE));
    }

    return bd;
}

parseConstructorArgElements()方法会解析Bean的构造函数参数。

public void parseConstructorArgElements(Element beanEle, BeanDefinition bd) {
    NodeList nl = beanEle.getChildNodes();
    for (int i = 0; i < nl.getLength(); i++) {
        Node node = nl.item(i);
        if (isCandidateElement(node) && nodeNameEquals(node, CONSTRUCTOR_ARG_ELEMENT)) {
            parseConstructorArgElement((Element) node, bd);
        }
    }
}

parsePropertyElements()方法会解析Bean的属性值。

public void parsePropertyElements(Element beanEle, BeanDefinition bd) {
    NodeList nl = beanEle.getChildNodes();
    for (int i = 0; i < nl.getLength(); i++) {
        Node node = nl.item(i);
        if (isCandidateElement(node) && nodeNameEquals(node, PROPERTY_ELEMENT)) {
            parsePropertyElement((Element) node, bd);
        }
    }
}

parseQualifierElements()方法会解析Bean的限定符(Qualifier)。

public void parseQualifierElements(Element beanEle, AbstractBeanDefinition bd) {
    NodeList nl = beanEle.getChildNodes();
    for (int i = 0; i < nl.getLength(); i++) {
        Node node = nl.item(i);
        if (isCandidateElement(node) && nodeNameEquals(node, QUALIFIER_ELEMENT)) {
            parseQualifierElement((Element) node, bd);
        }
    }
}

3.3 注册Bean定义

在解析完Bean定义后,Spring会将BeanDefinition对象注册到BeanFactory中。BeanDefinitionReaderUtils.registerBeanDefinition()方法负责将BeanDefinition注册到BeanFactory中。

public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
        throws BeanDefinitionStoreException {

    // 注册Bean定义
    String beanName = definitionHolder.getBeanName();
    registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

    // 注册别名
    String[] aliases = definitionHolder.getAliases();
    if (aliases != null) {
        for (String alias : aliases) {
            registry.registerAlias(beanName, alias);
        }
    }
}

DefaultListableBeanFactory类实现了BeanDefinitionRegistry接口,并提供了registerBeanDefinition()方法的实现。

@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
        throws BeanDefinitionStoreException {

    // 省略部分代码...
    this.beanDefinitionMap.put(beanName, beanDefinition);
    this.beanDefinitionNames.add(beanName);
    removeManualSingletonName(beanName);
}

4. 实例化Bean

在Spring容器初始化过程中,Bean的实例化是一个关键步骤。Spring容器会根据Bean定义创建Bean实例,并进行依赖注入。

4.1 Bean实例化的入口

Bean的实例化过程通常发生在finishBeanFactoryInitialization()方法中,该方法会实例化所有非懒加载的单例

推荐阅读:
  1. 如何构造函数初始化器
  2. java构造方法的用处是什么

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

spring

上一篇:Python正则表达式re.compile()和re.findall()怎么使用

下一篇:Python Sklearn中超实用的隐藏功能有哪些

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》