`
m635674608
  • 浏览: 5026980 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

spring中bean被多次实例化问题

 
阅读更多

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-paramlistener来达到目的,此时只剩下一个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顺序

    在Spring框架中,Bean的实例化顺序是一个关键概念,它涉及到如何管理和协调多个Bean的创建与依赖关系。这里,我们主要探讨的是Spring如何通过其IoC(Inversion of Control)容器来实例化Bean,并理解其背后的逻辑。 ...

    Spring Bean重复执行两次(实例被构造两次)问题分析

    对于Singleton作用域的Bean,Spring保证在整个容器生命周期内只有一个实例,如果违反这个规则,Bean可能会被多次实例化。 5. **AOP代理**:Spring的AOP代理机制也可能导致问题。当Bean被代理时,原始的Bean实例和...

    Spring Bean 加载顺序 .

    对于Singleton作用域的Bean,Spring会在容器启动时一次性实例化所有Bean。实例化顺序基于Bean的依赖关系和`@DependsOn`注解。如果Bean之间没有依赖关系,Spring将按照Bean定义的顺序实例化。对于Prototype作用域,...

    spring bean 属性总结

    - **abstract属性**:如果设置为`true`,则该Bean仅作为其他Bean的抽象模板,不能被直接实例化。 - **parent属性**:允许继承另一个Bean的属性。这对于共享一些通用配置非常有用。 - **autowire属性**:控制Bean的...

    spring 静态实例化

    在Spring框架中,静态实例化是指在应用程序启动时,即Spring容器初始化过程中创建Bean实例的过程。通常情况下,Spring会根据配置文件中的定义,在应用启动时自动创建和管理Bean实例。这种方式可以确保在应用运行期间...

    详解Spring中bean的scope以后使用

    当一个Bean被定义为Singleton时,Spring容器只会为这个Bean创建一个实例,并将其保存在单例缓存中。这意味着每当需要这个Bean时,Spring都会返回同一个实例。这有助于减少内存消耗和提高性能,尤其是在处理复杂的...

    spring的Bean配置说明

    `class`属性用于指定Bean的完整类名,确保Spring知道要实例化的对象类型。 3. `id` 和 `name` 属性:`id`属性为Bean提供一个唯一的标识,用于在代码中通过BeanFactory或ApplicationContext获取Bean实例。`name`属性...

    Spring的Bean配置说明

    - **`abstract`属性**:如果设置为`true`,表示这是一个抽象Bean,不能被实例化。主要用于定义共有的配置,子Bean可以继承这些配置。例如,定义一个日志级别的抽象配置,然后由具体的服务Bean继承这些配置。 - **`...

    spring java 定时器 执行两次 quartz

    总的来说,Spring集成Quartz提供了灵活的定时任务解决方案,但同时需要注意避免配置错误和并发问题,以防止任务被执行多次。通过理解Quartz的工作原理和Spring的定时任务API,我们可以有效地管理定时任务,确保它们...

    第四章 Spring Bean基础1

    - **延迟初始化**:Bean 只在第一次请求时才被实例化,减少资源消耗。 - **销毁**:容器关闭时,调用销毁方法释放资源,执行清理工作。 8. **垃圾回收**:Spring 不直接参与 JVM 的垃圾回收,但当 Bean 不再被...

    Spring实战之Bean的作用域singleton和prototype用法分析

    这意味着,如果多次从Spring容器中请求同一个`prototype` Bean,将会得到不同的对象。在配置文件中,`p2`被定义为`prototype` Bean,通过`scope="prototype"`指定。在`BeanTest`中,我们请求`p2`两次并进行比较,...

    spring bean的循环依赖完全掌握.pdf

    在 Spring 框架中,Bean 的循环依赖是指多个 Bean 之间存在相互依赖关系,导致 Bean 的创建和初始化过程变得复杂。为了彻底掌握 Spring Bean 的循环依赖,我们需要搞清楚四个问题:普通 Bean 的非循环依赖 Bean 生命...

    Spring定时任务(多个实例)

    在Spring框架中,定时任务是实现自动化操作的重要手段,它允许开发者在特定时间点执行特定的任务,例如数据清理、报表生成等。本篇文章将详细探讨Spring中的定时任务,包括配置方式、注解实现以及集成Quartz库进行更...

    浅谈Spring中Bean的作用域、生命周期

    * 实例化Bean * 设置Bean的属性 * 调用Bean的初始化方法 * 将Bean实例注册到容器中 * 销毁Bean实例 Spring中Bean的作用域和生命周期是两个非常重要的概念,对了解Spring框架的工作机理具有非常重要的意义。了解这些...

    spring bean加载

    - 如果在Bean定义中设置了`lazy-init="true"`,则Bean将在第一次请求时才实例化,而不是在容器启动时。 6. **AOP代理**: - Spring支持面向切面编程(AOP),可以为Bean创建代理对象,实现如事务管理、日志记录等...

    Spring--2.Spring 中的 Bean 配置-2-2

    在Spring框架中,Bean配置是核心概念之一,它关乎到对象的创建、初始化、依赖注入以及生命周期管理。在"Spring--2.Spring 中的 Bean 配置-2-2"这个主题下,我们将深入探讨如何在Spring中进行Bean的详细配置。 1. **...

    Spring bean为什么默认是单例

    当一个Bean被定义为单例时,Spring容器会在初始化时或第一次请求时创建Bean的实例,并将其存储在内部缓存中。后续的请求不再创建新的Bean,而是直接从缓存中获取已存在的实例。这种设计降低了新实例化的开销,包括...

    spring的quartz使用实例

    - 集成方便:Spring容器可以管理Job的生命周期,包括依赖注入,使得Job可以访问Spring上下文中的其他bean。 3. **配置步骤** - 引入依赖:在项目中添加Quartz和Spring相关库的依赖。 - 创建SchedulerFactoryBean...

    模拟Spring的IoC容器实现注解自动装配

    - **依赖注入**:在bean实例化后,处理@Autowired注解,完成依赖注入。 - **初始化回调**:调用bean的初始化方法,如 InitializingBean 的 afterPropertiesSet() 或 @PostConstruct 注解的方法。 - **单例管理**:...

Global site tag (gtag.js) - Google Analytics