The problem of bean being instantiated multiple times in spring

1. Description

Spring provides two main ways to instantiate beans, one is the configuration file method, and the other is the annotation form. However, if the configuration file configuration is unreasonable or the annotation is not used properly, it will cause a bean to be initialized multiple times. At this time, it will cause a waste of resources, and even affect the performance of the system in severe cases. But this kind of problem is very hidden, and it is difficult to find it without careful inspection. I found this problem after google and baidu because a timed task in the system was repeatedly executed twice. The following are several forms of configuration that can produce this problem.

2. Duplicate initialization caused by configuration file problems

2.1 Cause of the problem

Sometimes, we will put the spring configuration and spring mvc configuration in an xml file, such as: applicationContext.xml, at this time, when we initialize the spring container in the web.xml file, we generally do the following configuration

<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>

In the configuration here, context-paramthe applicationContext Servletused to initialize spring and the DispatcherServlet used to initialize spring will cause applicationContext.xmlthe bean to be initialized twice.

1.2 Solutions

In this case, you can delete the context-paramsum listenerto achieve the purpose. At this time, there is only one Servletconfiguration left, and all beans will be initialized once. However, there is a concept of parent-child container in spring, that is listener, the initialized applicationContext is Servletthe parent container of the initialized WebApplicationContext, and the child container can access the beans instantiated in the parent container, but the parent container cannot use the beans instantiated in the child container. , i.e. beans instantiated in ref subcontainers cannot be used. ** Therefore, in this case, the best solution is to applicationContext.xmlsplit the file into two files, and divide the functions and configurations in the two files according to business requirements.

3. Repeated initialization caused by annotation problems

3.1 Cause of the problem

If applicationContext.xmlyou configure beans in , and use annotations at the same time, the configuration is similar to the following:

<context:component-scanbase-package="com.zhlong.test"></context:component-scan>
<beanclass="com.zhlong.test.People">
</bean>

At the same time, annotations are used on the People class, similar to the following:

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

At this point, when the system starts, the people class will be initialized twice, generating two instances of the people class. You will find People类被初始化...that the sentence is printed twice.

3.2 Solutions

Configurations and annotations only use one way. Configure according to business needs. <div class="iteye-blog-content-contain" style="font-size: 14px"></div>

 

https://my.oschina.net/u/575836/blog/552394

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326566696&siteId=291194637