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

相關文章
相關標籤/搜索