Spring框架作为Java开发中最流行的轻量级容器之一,其核心功能之一就是依赖注入(DI)和面向切面编程(AOP)。Spring容器的初始化是Spring框架启动的关键步骤,理解Spring容器的初始化过程对于深入掌握Spring框架的工作原理至关重要。本文将详细解析Spring容器初始化的构造方法,从源码层面剖析Spring容器是如何一步步完成初始化的。
Spring容器是Spring框架的核心,负责管理应用中所有Bean的生命周期、依赖关系以及配置。Spring容器通过读取配置文件或注解来创建和管理Bean实例,并提供依赖注入、AOP等功能。
Spring容器主要有两种类型:
在本文中,我们将主要关注ApplicationContext
的初始化过程。
Spring容器的初始化过程可以分为以下几个主要步骤:
init-method
或@PostConstruct
注解)。接下来,我们将详细解析每个步骤的源码实现。
Spring容器的初始化通常从加载配置文件开始。Spring支持多种配置方式,包括XML配置、Java配置和注解配置。我们以XML配置为例,解析Spring容器如何加载配置文件。
Spring容器初始化的入口通常是ClassPathXmlApplicationContext
或FileSystemXmlApplicationContext
。这两个类都继承自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(); } }
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()
方法最终会调用XmlBeanDefinitionReader
的loadBeanDefinitions()
方法,该方法会解析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的属性,如scope
、lazy-init
、depends-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); } } }
在解析完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); }
在Spring容器初始化过程中,Bean的实例化是一个关键步骤。Spring容器会根据Bean定义创建Bean实例,并进行依赖注入。
Bean的实例化过程通常发生在finishBeanFactoryInitialization()
方法中,该方法会实例化所有非懒加载的单例
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。