探秘 ThreadLocal 的实现机制与小地雷

Java 多线程类库对于共享数据的读写访问主要采用同步机制来保证线程安全,而本文所要探究的 ThreadLocal 则采用了一种完全不同的策略,它不是用来解决共享数据的并发访问问题的,ThreadLocal 让每个线程都将目标数据复制一份作为线程私有,后续对于该数据的操作都是在各自私有的副本上进行,线程之间彼此相互隔离,也就不存在竞争问题。

下面的例子演示了 ThreadLocal 的典型应用场景。在 jdk 1.8 之前,如果我们希望对日期和时间进行格式化操作,则需要使用 SimpleDateFormat 类,而我们知道它是是线程不安全的,在多线程并发执行时会出现一些奇怪的问题。

阅读全文

Spring MVC 源码解析:跟踪一次简单的请求处理过程

上一篇我们分析了 web 环境下容器的初始化过程,探究了在 web 项目启动过程中,Spring MVC 所执行的一系列初始化工作,本篇中我们将一起来跟踪一次 Spring MVC 对于请求的具体处理过程,从整体上对 Spring MVC 的逻辑处理进行感知,先把握整体,后追究细节。

阅读全文

Spring MVC 源码解析:Web 环境下容器的初始化过程

Spring MVC 是目前最流行的 java web 框架(之一),是对传统 servlet 的高级封装,以提升 servlet 的灵活性和易用性。从广义上来说,Spring MVC 的执行过程可以分为 容器初始化请求响应处理 两大部分,前者在 servlet 容器启动过程中完成,为后者的执行提供基本的运行环境,而后者则是 Spring MVC 的核心所在,负责接收请求到最终返回响应数据的复杂处理过程。

阅读全文

Spring AOP 源码解析:注解式切面增强机制

IoC 和 AOP 被称为 Spring 两大基础模块,支撑着上层扩展的实现和运行。虽然 AOP 同样建立在 IoC 的实现基础之上,但是作为对 OOP(Object-Oriented Programing) 的补充,AOP(Aspect-Oriented Programming) 在程序设计领域拥有其不可替代的适用场景和地位。Spring AOP 作为 AOP 思想的实现,被誉为 Spring 框架的基础模块也算是实至名归。Spring 在 1.0 版本的时候就引入了对 AOP 的支持,并且随着版本的迭代逐渐提供了基于 XML 配置、注解,以及 schema 配置的使用方式,考虑到实际开发中使用注解配置的方式相对较多,所以本文主要分析注解式 AOP 的实现和运行机制。

阅读全文

Spring IoC 源码解析:循环依赖的检测与处理

Spring 为开发人员提供了极其灵活和强大的配置使用方式,在方便开发的同时也为容器的初始化过程带来了不确定性。本文所要介绍的循环依赖就是其中之一,尤其在一些大型项目中,循环依赖的配置往往是我们不经意而为之的,幸好 Spring 能够在初始化的过程中检测到对象之间的循环依赖,并能够在一定程度上予以处理。

阅读全文

Spring IoC 源码解析:高级容器的初始化过程

前面的几篇文章我们一直围绕着 BeanFactory 分析容器的初始化和依赖注入过程,本篇我们将从 ApplicationContext 触发探究容器的高级形式。ApplicationContext 相对于 BeanFactory 扩展了许多实用功能,方便开发者的使用。二者的结构设计我们在前面的文章中已经介绍过,本篇将详细分析基于 ApplicationContext 的容器初始化和注入过程。

阅读全文

Spring IoC 源码解析:创建和初始化 bean 实例

到目前为止,我们已经分析了 bean 配置的解析与注册过程。经过这一系列的操作,我们编写在 XML 中的半结构化静态配置已经转换成一个个的 BeanDefinition 实例存在于容器之中,接下来就可以调用 BeanFactory#getBean 方法获取目标 bean 实例。本文我们将从 BeanFactory#getBean 方法出发,探究容器基于 BeanDefinition 创建和初始化 bean 实例的过程。

阅读全文

Spring IoC 源码解析:自定义标签的解析过程

Spring 中的标签分为默认标签和自定义标签两类,上一篇我们分析了默认标签的解析过程,当然在分析过程中我们也看到默认标签中嵌套了对自定义标签的解析,这是因为默认标签中可以嵌套使用自定义标签。然而,这和本篇所要讨论的自定义标签还是有些区别的,上一篇中介绍的自定义标签可以看作是 <bean /> 标签的子标签元素,而本篇所要分析的自定义标签是与 <bean /> 这类标签平级的标签。

阅读全文

Spring IoC 源码解析:默认标签的解析过程

上一篇我们梳理了容器初始化的整体流程,了解了一个 bean 是如何从静态配置变为一个可运行的实例的,但是对于过程中涉及到的具体细节并未进行深入探究。从本篇开始,我们将回到起点重新沿着主线走一遍,与之前不同的是,这一次我们更加关注细节。

由前面的分析我们已经大致知晓 IoC 容器在初始化期间主要分为两个阶段:加载并解析配置文件和初始化 bean 实例。本文所要介绍的对于默认标签的解析发生在加载并解析配置文件阶段,以 XML 配置为例,容器会将 XML 形式的静态配置解析成对应的 BeanDefinition 对象注册到容器中。在配置方面,Spring 为开发者提供了许多可用的标签,比如 <beans /><bean /><import />,以及 <alias /> 等等。这些标签统称为 默认标签 (个人觉得翻译成内置标签更加合理),同时 Spring 还允许开发者自己定义标签,方法 DefaultBeanDefinitionDocumentReader#parseBeanDefinitions 中的逻辑就是判断当前标签是默认标签还是自定义标签,并调用相应的方法对标签进行解析(实现如下),本篇我们主要分析默认标签的解析过程,对于自定义标签则留到下一篇进行讲解。

阅读全文

Spring IoC 源码解析:简单容器的初始化过程

本文将主要对定义在 XML 文件中的 bean 从静态配置到加载成为可使用对象的过程,即 IoC 容器的初始化过程进行一个整体的分析。在讲解上不主张对各个组件进行深究,只求对简单容器的实现有一个整体的认识,具体实现细节留到后面专门用针对性的篇章进行讲解。

首先我们引入一个 Spring 入门示例,假设我们现在定义了一个类 MyBean,我们希望利用 Spring 管理类对象。

阅读全文