private final ThreadLocal<Set<EncodedResource>> resourcesCurrentlyBeingLoaded = new NamedThreadLocal<>("XML bean definition resources currently being loaded");
昨天看Spring加载配置文件源码时,对于XmlBeanDefinitionReader中resourcesCurrentlyBeingLoaded的作用一直很疑惑,今天终于弄明白。特写下此片文章,用于记录
resourcesCurrentlyBeingLoaded是ThreadLocal的,每个线程获取的都是不同的内存。它的作用是为了防止循环加载同一个配置文件(在beans.xml中import本身)
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException { Assert.notNull(encodedResource, "EncodedResource must not be null"); if (logger.isInfoEnabled()) { logger.info("Loading XML bean definitions from " + encodedResource.getResource()); } //获取当前线程中已加载的resource Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get(); if (currentResources == null) { currentResources = new HashSet<>(4); this.resourcesCurrentlyBeingLoaded.set(currentResources); } //如果resource已经加载,就抛出异常(只有使用import引入自己的配置文件时才会导致异常) if (!currentResources.add(encodedResource)) { throw new BeanDefinitionStoreException( "Detected cyclic loading of " + encodedResource + " - check your import definitions!"); } try { InputStream inputStream = encodedResource.getResource().getInputStream(); try { InputSource inputSource = new InputSource(inputStream); if (encodedResource.getEncoding() != null) { inputSource.setEncoding(encodedResource.getEncoding()); } /** * doLoadBeanDefinitions解析配置文件时,遇到import标签会递归调用loadBeanDefinitions方法 * 这个时候当前加载配置文件不会清除 */ int num = doLoadBeanDefinitions(inputSource, encodedResource.getResource()); System.out.println(num); return num; } finally { inputStream.close(); } } catch (IOException ex) { throw new BeanDefinitionStoreException( "IOException parsing XML document from " + encodedResource.getResource(), ex); } finally { //每次加载完就会从resourcesCurrentlyBeingLoaded清除掉当前加载的resource文件, //这样之后可以重新加载配置文件 currentResources.remove(encodedResource); if (currentResources.isEmpty()) { this.resourcesCurrentlyBeingLoaded.remove(); System.out.println(this.resourcesCurrentlyBeingLoaded.get()); } } }
相关推荐
Spring 源码分析 Spring 框架是 Java 语言中最流行的开源框架之一,它提供了一个强大且灵活的基础设施来构建企业级应用程序。在 Spring 框架中,IOC 容器扮演着核心角色,本文将深入分析 Spring 源码,了解 IOC ...
Spring框架是Java后端开发中不可或缺的部分,它提供了一个全面的编程和配置...通过源码学习,开发者可以更好地掌握Spring如何管理和创建Bean,以及如何利用注解进行组件扫描,这对于解决复杂问题和提升性能非常关键。
### Spring源码解析知识点 #### 一、Spring IoC 容器详解 ##### 1. BeanFactory —— 最基础的IoC容器 - **概念**:`BeanFactory` 是Spring框架中最基本的IoC容器,它负责管理Bean的生命周期,包括创建、配置和...
通过对`spring-beans`源码的深入学习,我们可以更好地理解Spring的工作机制,从而更高效地利用这一强大框架。这有助于我们编写出更加灵活、可维护的代码,提升项目的整体质量。在实际开发中,理解并掌握这些知识点将...
Spring 源码学习五:BeanDefinition 装载 1 在 Spring 框架中,BeanDefinition 是一个核心概念,它描述了一个 Bean 的定义,包括其依赖项、作用域、生命周期等信息。在本篇文章中,我们将深入探讨 Spring 的源码,...
### Spring源码分析_Spring_IOC:深入理解Spring的IOC容器机制 #### 基本概念与核心作用 在探讨Spring框架的核心组件之一——IOC(Inversion of Control,控制反转)容器之前,首先需要理解它在Spring框架中的角色...
在Spring Framework中,IoC(Inversion of Control,控制反转)是核心概念之一,它使得应用程序的组件不再直接创建依赖对象,而是由Spring容器来管理和维护。BeanDefinition就是实现这一概念的关键元素,它包含了...
是Spring注册及加载bean的默认实现,XmlBeanFactory与DefaultListableBeanFactory不同的地方其实是在XmlBeanFactory中使用了自定义的XML读取器XmlBeanDefinitionReader,实现了个性化的BeanDefinitionReader读取。
通过对Spring Framework 3.2.5源代码的阅读和学习,开发者不仅能深入了解Spring的内部工作原理,还能提升自己的设计思想,更好地应用到实际项目中,提高代码质量和可维护性。在不断发展的软件工程领域,理解和掌握...
### Spring IoC源码解读 #### 一、Spring IoC 容器概述 Spring框架的核心功能之一便是依赖注入(Dependency Injection, DI),而这一功能主要通过IoC容器来实现。在Spring框架中,IoC容器负责管理应用对象的生命...
通过源码分析Spring,可以帮助开发者深入理解Spring的运作机制,掌握其核心编程思想。 首先,BeanFactory是Spring中IOC容器的基础接口,它负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖关系。...
面向切面编程(AOP)是Spring框架提供的另一个核心功能,用于将横切关注点(如日志记录、安全控制、事务管理等)从业务逻辑中分离出来。通过Spring AOP,可以在不修改业务逻辑代码的情况下,为多个不同的服务添加相同...
3. Spring源码学习: - Bean生命周期:了解Spring如何创建、初始化、装配、销毁Bean,以及AOP代理的实现原理。 - 事件驱动:Spring的ApplicationEvent和ApplicationContextEventListener机制,用于在应用上下文间...
spring源码剖析,大部分都是基于Springframework5.0 交代: spring最核心的两个类: DefaultListableBeanFactory && XmlBeanDefinitionReader 容器的基础XMLBeanFactory XmlBeanFactory继承自...
### Spring源码分析之IOC容器深入探讨 #### 一、Spring框架及IOC容器概述 Spring框架作为企业级Java开发中最常用的轻量级框架之一,以其强大的功能和灵活的设计深受开发者们的喜爱。Spring的核心特性之一便是...
Spring 源码解析系列将深入探讨 Spring 框架的...总的来说,理解 Spring 的源码对于深入学习和优化应用性能至关重要。通过阅读和分析源码,开发者可以更好地掌握 Spring 的设计原则,从而更高效地利用这个强大的框架。
在深入探讨Spring源码之前,我们首先要理解什么是Spring...对于Spring框架的学习者和开发者来说,深入理解IOC容器及其源码是不可或缺的一部分,这对于提高设计能力、优化代码质量以及解决实际问题都将带来巨大的帮助。