1. 描述
spring中提供了两种主要方式实例化bean,一种为配置文件方式,另一种为注解的形式。但如果配置文件配置不合理或者注解使用不恰当,就会造成一个bean会被多次初始化的现象发生。此时会造成一种资源的浪费,严重时甚至会影响系统的性能。但此种问题有很隐蔽,如果不仔细检查,很难发现。本人是因为系统中一个定时任务被重复执行两次,经google,baidu之后才发现此问题。 以下是几种会产生此问题的配置形式。
2. 配置文件问题导致的重复初始化
2.1 问题原因
有时候,我们会将spring的配置和spring mvc的配置放在一个xml文件中,比如叫:applicationContext.xml,此时,我们在web.xml文件中初始化spring容器时,一般会做如下形式的配置
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- 配置Spring的监听,否则业务层的bean实例无法创建,也就不能使用spring的ioc了 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
在此处配置中,context-param
用于初始化spring的applicationContext,Servlet
用于初始化spring的DispatcherServlet,此时就会造成applicationContext.xml
中的bean会被重复初始化两次。
1.2 解决方案
此种情况,可以删除context-param
和listener
来达到目的,此时只剩下一个Servlet
的配置,所有bean都会被初始化一次。但是spring中有个父子容器的概念,即listener
中初始化的applicationContext是Servlet
初始化的WebApplicationContext的父容器,**子容器可以访问使用父容器中实例化的bean,但是父容器不能使用子容器中实例化的bean,即不能使用ref子容器中实例化的bean。**所以,此种情况下,最好的解决方法是:将applicationContext.xml
文件拆成两个文件,并根据业务需求划分两个文件中的功能和配置。
3. 注解问题导致的重复初始化
3.1 问题原因
如果在applicationContext.xml
中配置bean,同时用了注解,配置类似如下:
<context:component-scanbase-package="com.zhlong.test"></context:component-scan>
<beanclass="com.zhlong.test.People">
</bean>
同时People类上使用了注解,类似如下:
@Component
public class People {
public People(){
System.out.println("People类被初始化...");
}
}
此时系统启动时,people类会被初始化两次,生成两个people类实例。会发现People类被初始化...
这句话被打印两次。
3.2 解决方案
配置和注解只使用一种方式。根据业务需要配置。<div class="iteye-blog-content-contain" style="font-size: 14px"></div>
https://my.oschina.net/u/575836/blog/552394
相关推荐
在Spring框架中,Bean的实例化顺序是一个关键概念,它涉及到如何管理和协调多个Bean的创建与依赖关系。这里,我们主要探讨的是Spring如何通过其IoC(Inversion of Control)容器来实例化Bean,并理解其背后的逻辑。 ...
对于Singleton作用域的Bean,Spring保证在整个容器生命周期内只有一个实例,如果违反这个规则,Bean可能会被多次实例化。 5. **AOP代理**:Spring的AOP代理机制也可能导致问题。当Bean被代理时,原始的Bean实例和...
对于Singleton作用域的Bean,Spring会在容器启动时一次性实例化所有Bean。实例化顺序基于Bean的依赖关系和`@DependsOn`注解。如果Bean之间没有依赖关系,Spring将按照Bean定义的顺序实例化。对于Prototype作用域,...
- **abstract属性**:如果设置为`true`,则该Bean仅作为其他Bean的抽象模板,不能被直接实例化。 - **parent属性**:允许继承另一个Bean的属性。这对于共享一些通用配置非常有用。 - **autowire属性**:控制Bean的...
在Spring框架中,静态实例化是指在应用程序启动时,即Spring容器初始化过程中创建Bean实例的过程。通常情况下,Spring会根据配置文件中的定义,在应用启动时自动创建和管理Bean实例。这种方式可以确保在应用运行期间...
当一个Bean被定义为Singleton时,Spring容器只会为这个Bean创建一个实例,并将其保存在单例缓存中。这意味着每当需要这个Bean时,Spring都会返回同一个实例。这有助于减少内存消耗和提高性能,尤其是在处理复杂的...
`class`属性用于指定Bean的完整类名,确保Spring知道要实例化的对象类型。 3. `id` 和 `name` 属性:`id`属性为Bean提供一个唯一的标识,用于在代码中通过BeanFactory或ApplicationContext获取Bean实例。`name`属性...
- **`abstract`属性**:如果设置为`true`,表示这是一个抽象Bean,不能被实例化。主要用于定义共有的配置,子Bean可以继承这些配置。例如,定义一个日志级别的抽象配置,然后由具体的服务Bean继承这些配置。 - **`...
总的来说,Spring集成Quartz提供了灵活的定时任务解决方案,但同时需要注意避免配置错误和并发问题,以防止任务被执行多次。通过理解Quartz的工作原理和Spring的定时任务API,我们可以有效地管理定时任务,确保它们...
- **延迟初始化**:Bean 只在第一次请求时才被实例化,减少资源消耗。 - **销毁**:容器关闭时,调用销毁方法释放资源,执行清理工作。 8. **垃圾回收**:Spring 不直接参与 JVM 的垃圾回收,但当 Bean 不再被...
这意味着,如果多次从Spring容器中请求同一个`prototype` Bean,将会得到不同的对象。在配置文件中,`p2`被定义为`prototype` Bean,通过`scope="prototype"`指定。在`BeanTest`中,我们请求`p2`两次并进行比较,...
在 Spring 框架中,Bean 的循环依赖是指多个 Bean 之间存在相互依赖关系,导致 Bean 的创建和初始化过程变得复杂。为了彻底掌握 Spring Bean 的循环依赖,我们需要搞清楚四个问题:普通 Bean 的非循环依赖 Bean 生命...
在Spring框架中,定时任务是实现自动化操作的重要手段,它允许开发者在特定时间点执行特定的任务,例如数据清理、报表生成等。本篇文章将详细探讨Spring中的定时任务,包括配置方式、注解实现以及集成Quartz库进行更...
* 实例化Bean * 设置Bean的属性 * 调用Bean的初始化方法 * 将Bean实例注册到容器中 * 销毁Bean实例 Spring中Bean的作用域和生命周期是两个非常重要的概念,对了解Spring框架的工作机理具有非常重要的意义。了解这些...
- 如果在Bean定义中设置了`lazy-init="true"`,则Bean将在第一次请求时才实例化,而不是在容器启动时。 6. **AOP代理**: - Spring支持面向切面编程(AOP),可以为Bean创建代理对象,实现如事务管理、日志记录等...
在Spring框架中,Bean配置是核心概念之一,它关乎到对象的创建、初始化、依赖注入以及生命周期管理。在"Spring--2.Spring 中的 Bean 配置-2-2"这个主题下,我们将深入探讨如何在Spring中进行Bean的详细配置。 1. **...
当一个Bean被定义为单例时,Spring容器会在初始化时或第一次请求时创建Bean的实例,并将其存储在内部缓存中。后续的请求不再创建新的Bean,而是直接从缓存中获取已存在的实例。这种设计降低了新实例化的开销,包括...
- 集成方便:Spring容器可以管理Job的生命周期,包括依赖注入,使得Job可以访问Spring上下文中的其他bean。 3. **配置步骤** - 引入依赖:在项目中添加Quartz和Spring相关库的依赖。 - 创建SchedulerFactoryBean...
- **依赖注入**:在bean实例化后,处理@Autowired注解,完成依赖注入。 - **初始化回调**:调用bean的初始化方法,如 InitializingBean 的 afterPropertiesSet() 或 @PostConstruct 注解的方法。 - **单例管理**:...