SPRING已经几乎成为我们日常开发必不可少的框架了,它对IOC以及AOP思想的实现得到了广泛的认可和推崇。
IOC作为一个容器,管控了大部分运行期的JAVA对象,由于IOC的高可配置性,使得传统的JAVA工厂模式,单例模式几乎不再出现于代码中。
然而本文的标题何故冠以诡异二字,这还得从一次项目组遇到的问题说起。
这个项目不无例外地使用了SPRING框架。然而在应用启动一段时间后,原本运行中没问题的一些对象,会忽然“无故”地报错找不到,出现Spring容器getBean失败。而这些对象在应用重启以后又是可以找到的!这使得项目组的同事百思不得其解。而且出现这些对象不见的时机也很蹊跷,时而隔天出现,时而隔一小时就报错。
此时,传说中的神器SPRING仿佛成了一个难以捉摸的幽灵,IOC容器则成了一个黑洞,时不时地把对象给吞了,不得不说诡异二字。真的是这样么,我们展开了一番排摸。
我们发现,当出现对象找不到的情况时,去获取这些对象用的是一个ApplicationContextUtil工具类,这个工具类继承实现了Spring的ApplicationContextAware,并且注册到IOC的配置XML里,按照SPRING的加载机制,会自动把ApplicationContext交到ApplicationContextUtil手里。而这次,这个工具好像出问题了。
同时我们又发现,在这种情况下,使用WebApplicationContextUtils.getWebApplicationContext(ServletContext sc)来获取ApplicationContext的时候,这些丢失的类都还在里面!
至此,问题是不是变得更为扑朔迷离?还是渐渐有了头绪?
这种情况下,感觉可能是运行期存在了多个IOC容器。经过代码排查,果然发现在这个项目引用JAR包的一个工具类里,存在这样的写法:
private static final String CONTEXT_FILE_NAME = "/applicationContext-service.xml";
private static ApplicationContext fac=null;
public AdapterServiceFactory(String str) {
fac = new ClassPathXmlApplicationContext(
CONTEXT_FILE_NAME);
((AbstractApplicationContext) fac).registerShutdownHook();
this.serviseName=str;
}
也就是说,一旦利用这个工具获取对象,就会产生一个额外的IOC容器。
如此这个问题就变得很明了了,IOC容器没有错,错的是运行期产生了多个IOC容器。
新容器产生的同时,将实现了ApplicationContextAware的工具类ApplicationContextUtil中的ApplicationContext给覆盖了,因此ApplicationContextUtil只能读到applicationContext-service.xml这个文件中的配置类,而其他对象都丢失了。但在使用WebApplicationContextUtils这个方法的时候,取得的IOC容器是另一个,这个时候,其他的对象都还在!而这一切都是要看这个新的IOC容器何时产生,因此出现问题的时间是随机的。在出现问题后重启应用,则暂时只会存在一个IOC容器,看似一切正常。
终于,诡异的疑云消散了。之后就是对于这个问题的改造了。
改造就很简单了,将在代码中生成IOC容器new ClassPathXmlApplicationContext()的代码去掉,将该类改为实现ApplicationContextAware,通过Spring自身的web加载机制来获的。
分享到:
相关推荐
spring Ioc容器配置 IOC容器数据源配置 <!-- 配置数据源 --> destroy-method="close"> <value>org.gjt.mm.mysql.Driver <value>jdbc:mysql://localhost:3306/demo <value>root ...
《Spring IOC容器实现分析》 在Java开发领域,Spring框架无疑是使用最为广泛的轻量级框架之一,其中的核心组件就是IOC(Inversion of Control)容器。本文将深入剖析Spring的IOC容器,理解其工作原理和重要功能,以...
Spring IoC容器是Spring框架的核心,它负责管理应用对象的生命周期和依赖关系。通过对IoC(Inversion of Control,控制反转)的实现,Spring容器将对象的创建和组装工作从应用代码中分离出来,使得应用更易于测试和...
本项目"手写一个SpringIoc容器"旨在模仿Spring的IOC(Inversion of Control,控制反转)功能,帮助开发者深入理解Spring的工作原理,提升对依赖注入(Dependency Injection)模式的认识。 在实现自定义的Spring IOC...
以下是Spring IOC容器的主要知识点: 1. **Bean的定义**:在Spring中,业务对象被称为Bean。Bean定义包含了创建和管理Bean的所有信息,如类名、属性值、依赖关系等,通常通过XML、注解或Java配置来定义。 2. **...
自己动手实现Spring IoC容器, 写Spring IOC容器.wps写Spring IOC容器.wps写Spring IOC容器.wps
Spring Ioc容器是整个Spring框架的基石,它负责创建、配置和管理对象。容器通过读取XML、Java注解或Java配置类等方式,获取对象的定义信息,然后根据这些信息实例化对象并进行依赖注入。 **三、依赖注入(DI,...
### Spring的IoC容器初始化源码解析 #### 一、Spring框架的核心——IoC容器 Spring框架是一个开源的轻量级Java开发框架,其核心功能是IoC(Inversion of Control,控制反转)容器和AOP(Aspect Oriented ...
IoC(Inversion of Control)是 Spring 框架中的一种设计模式,它的主要思想是将对象的创建和管理交给容器,从而解耦合对象之间的依赖关系。今天,我们将详细解析 IoC 的优点和缺点。 优点 1. 简化对象的创建:IoC ...
Spring IOC 容器启动流程分析 Spring IOC 容器是 Java 企业级应用程序的核心组件之一,它提供了一个统一的依赖注入机制,使得应用程序的组件之间能够松耦合。Spring IOC 容器的启动流程是整个 Spring 框架的核心...
在Java Spring框架中,Spring IoC(Inversion of Control,控制反转)是核心特性之一,它使得应用程序的组件之间的依赖关系不再由代码直接管理,而是交由Spring IoC容器负责。这种设计模式降低了代码间的耦合,提高...
**Spring IOC 容器应用实例** Spring 框架的核心组件之一是 Inversion of Control (IoC) 容器,也常被称为依赖注入(Dependency Injection)容器。IoC 是一种设计模式,它将对象的创建和管理从应用程序的业务逻辑中...
### Spring IoC容器部署实现详解 #### 一、Spring IoC容器概述 Spring框架的核心特性之一就是Inversion of Control(IoC),也被称为Dependency Injection(DI)。IoC容器是Spring框架的重要组成部分,它负责管理...
在本教程中,我们将深入探讨如何通过XML配置在Spring IOC容器中实现依赖注入。 首先,我们需要了解Spring的IOC容器。IOC容器是Spring的核心,它负责管理对象的生命周期和对象间的依赖关系。容器通过读取XML配置文件...
IoC容器是Spring实现这一理念的重要工具,它负责管理对象的生命周期和对象之间的依赖关系。本教程将通过一个简单的模拟来帮助你快速理解Spring的IoC容器。 首先,我们要了解IoC的基本概念。IoC是指应用程序的控制...
### Spring IOC容器实现分析 #### 一、Spring IOC容器概览 Spring框架作为一款轻量级的开源框架,其核心之一便是IOC(Inversion of Control)容器。该容器的主要功能在于管理和控制对象间的依赖关系,使得开发人员...
"仿spring ioc 容器"这个主题,旨在探讨如何理解和实现类似于Spring框架中的IoC容器的功能。 IoC容器是Spring的核心,它负责创建对象、管理对象间的依赖关系以及对象的生命周期。在Spring中,IoC使得开发者不再需要...
而注解自动装配(Autowired)是Spring IoC容器的一种高级特性,它允许我们通过注解来声明对象之间的依赖,无需手动编写XML配置。现在,我们将深入探讨如何模拟Spring的IoC容器实现注解自动装配。 首先,我们需要...