温馨提示×

温馨提示×

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

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

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

发布时间:2022-07-07 13:58:55 来源:亿速云 阅读:186 作者:iii 栏目:开发技术

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容器主要有两种类型:

  • BeanFactory:Spring框架中最基本的容器,提供了基本的依赖注入功能。
  • ApplicationContext:BeanFactory的子接口,提供了更多的企业级功能,如国际化、事件传播、资源加载等。

在本文中,我们将主要关注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()方法中,该方法会实例化所有非懒加载的单例

向AI问一下细节

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

AI