spring中bean被屡次实例化问题

1. 描述

spring中提供了两种主要方式实例化bean,一种为配置文件方式,另外一种为注解的形式。但若是配置文件配置不合理或者注解使用不恰当,就会形成一个bean会被屡次初始化的现象发生。此时会形成一种资源的浪费,严重时甚至会影响系统的性能。但此种问题有很隐蔽,若是不仔细检查,很难发现。本人是由于系统中一个定时任务被重复执行两次,经google,baidu以后才发现此问题。 如下是几种会产生此问题的配置形式。web

2. 配置文件问题致使的重复初始化

2.1 问题缘由

有时候,咱们会将spring的配置和spring mvc的配置放在一个xml文件中,好比叫:applicationContext.xml,此时,咱们在web.xml文件中初始化spring容器时,通常会作以下形式的配置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会被重复初始化两次。mvc

1.2 解决方案

此种状况,能够删除context-paramlistener来达到目的,此时只剩下一个Servlet的配置,全部bean都会被初始化一次。可是spring中有个父子容器的概念,即listener中初始化的applicationContext是Servlet初始化的WebApplicationContext的父容器,**子容器能够访问使用父容器中实例化的bean,可是父容器不能使用子容器中实例化的bean,即不能使用ref子容器中实例化的bean。**因此,此种状况下,最好的解决方法是:将applicationContext.xml文件拆成两个文件,并根据业务需求划分两个文件中的功能和配置。app

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类上使用了注解,相似以下:google

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

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

3.2 解决方案

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

相关文章
相关标签/搜索