文档章节

spring中bean被多次实例化问题

z_hlong
 z_hlong
发布于 2015/12/28 16:46
字数 711
阅读 730
收藏 1

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-scan base-package="com.zhlong.test"></context:component-scan>
<bean class="com.zhlong.test.People">
</bean>

同时People类上使用了注解,类似如下:

@Component
public class People {
    public People(){
        System.out.println("People类被初始化...");
    }
}

此时系统启动时,people类会被初始化两次,生成两个people类实例。会发现People类被初始化...这句话被打印两次。

3.2 解决方案

配置和注解只使用一种方式。根据业务需要配置。

© 著作权归作者所有

共有 人打赏支持
z_hlong
粉丝 5
博文 4
码字总数 2167
作品 0
南京
Spring MVC 解读——@Autowired

Spring MVC 解读——@Autowired 一、@Autowired 作为一个Spring开发者对@Autowired注解必定是非常了解了, 顾名思义自动装配,应该是Spring会自动将我们标记为@Autowired的元素装配好,与其猜...

麦壳原野
2014/02/28
0
14
spring4.1.8扩展实战之七:控制bean(BeanPostProcessor接口)

版权声明:欢迎转载,请注明出处,谢谢。 https://blog.csdn.net/boling_cavalry/article/details/82250986 本章是《spring4.1.8扩展实战》的第七篇,我们来尝试在容器初始化的时候对bean实例...

博陵精骑
09/02
0
0
day33_Spring学习笔记_01

零、蓦然回首 Struts2:web层,比较简单(难点:ValueStack值栈、拦截器) Hibernate:dao层,知识点杂(学了不用,默认设置够用了) Spring:service层,重要,(讲多少用多少) Spring课程...

黑泽明军
07/22
0
0
解决Spring中singleton的Bean依赖于prototype的Bean的问题

当Spring容器中作用域不同的Bean相互依赖时,可能出现一些问题,例如:一个作用域为Singleton的Bean(设为A)依赖于一个作用域为prototype的Bean(设为B)。由于A是单例的,只有一次初始化的...

摆渡者
2014/03/06
0
0
spring循环依赖的三种方式

1.构造器参数循环依赖 对象间在构造函数中有相互依赖,通过构造函数注入 constructor-arg 启动是会报循环依赖错误 2.setter方式单例,默认方式 spring先通过无参构造方法创建bean,然后通过s...

素雷
08/08
0
0

没有更多内容

加载失败,请刷新页面

加载更多

spring只

一、IOC(Inversion of Control)或者依赖注入(Dependency Injection) 1、底层实现原理:反射 2、三大核心接口: BeanFactory:简单容器系列,只是实现了容器最基本的功能。 ApplicationC...

狠一点
10分钟前
4
0
缓存架构SpringBoot集成Curator实现zookeeper分布式锁

一、分布式锁简介 1、什么是锁 在单机环境下,当存在多个线程可以同时改变某个共享变量时,就需要同步来实现该功能,使其线程安全。 而同步就是通过锁来实现的。锁保证了同一时刻只有一个线程...

架构师springboot
12分钟前
1
0
11《Java核心技术》之Java提供了哪些IO方式? NIO如何实现多路复用?

一、提出问题 IO 一直是软件开发中的核心部分之一,伴随着海量数据增长和分布式系统的发展,IO 扩展能力愈发重要。幸运的是,Java 平台 IO 机制经过不断完善,虽然在某些方面仍有不足,但已经...

飞鱼说编程
19分钟前
1
0
简单介绍Java 的JAR包、EAR包、WAR包区别

WAR包 WAR(Web Archive file)网络应用程序文件,是与平台无关的文件格式,它允许将许多文件组合成一个压缩文件。War专用于Web方面。大部分的JAVA WEB工程,都是打成WAR包进行发布的。 War是...

linuxprobe16
19分钟前
1
0
55:Mysql用户管理|常用sql语句|mysql数据库备份恢复

1、Mysql用户管理; 场景,为了安全,新建的站点,创建新的用户,或者给已有用户授权,对某个库或者某个表有权限; 语法: grant all on *.* to 'user'@'127.0.0.1' identified by 'password'; g...

芬野de博客
23分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部