Spring正在创建多个bean实例 [英] Spring multiple bean instances being created

查看:103
本文介绍了Spring正在创建多个bean实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经使用autowire @Controller创建了一个称为RegistrationController的弹簧控制器.为了我自己的好奇心,我创建了一个默认的构造函数,如下所示,并添加了一条logger语句:

I have created a spring controller called RegistrationController using autowire @Controller. I have for my own curiosity sake created a default constructor as follows and added a logger statement:

public RegistrationController() {
    logger.info("Registration Controller (Constructor) called-->"+this);
}

我发现的是,当我在日志文件中的spring source IDE(v2.9)中启动tomcat服务器(v7)时,看到以下内容:

What I found was when I start my tomcat server (v7) in spring source IDE (v2.9) in the log file I see the following:

INFO: Initializing Spring root WebApplicationContext
2012-08-15 15:12:28,808 [pool-2-thread-1] INFO  com.controllers.registration.RegistrationController - Registration Controller (Constructor) called-->com.controllers.registration.RegistrationController@78c0dc2
Aug 15, 2012 3:12:28 PM org.apache.catalina.core.ApplicationContext log
INFO: Initializing Spring FrameworkServlet 'main'
2012-08-15 15:12:29,256 [pool-2-thread-1] INFO  com.controllers.registration.RegistrationController - Registration Controller (Constructor) called-->com.controllers.registration.RegistrationController@773ba8d6

我知道默认情况下RegistrationController应该是单例对象,并且只能创建一个实例.但是,从日志文件中可以看到,创建了两个实例.我以某种方式认为这是不正确的.但是我没有确切的答案.

I understand that the RegistrationController by default should be singleton object and only one instance must be created. However, as you can see from the log file that two instances are created. Somehow I feel this is not correct. But I don't have the exact answer.

我的web.xml中的一些重要内容如下:

Some of the important lines from my web.xml are as follows:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>/WEB-INF/classes/applicationContext*.xml</param-value>
</context-param>
.
.
 <servlet>
    <servlet-name>main</servlet-name>
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <load-on-startup>2</load-on-startup>
</servlet>



<servlet-mapping>
    <servlet-name>main</servlet-name>
    <url-pattern>*.htm</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>main</servlet-name>
    <url-pattern>*.jspx</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>main</servlet-name>
    <url-pattern>*.do</url-pattern>
</servlet-mapping>
   .
   .
   </web-app>

您可能已经猜到了,我有一个main-servlet.xml和applicationContext.xml作为我的spring配置文件.

As you must have guessed, I have a main-servlet.xml and applicationContext.xml as my spring configuration files.

您能帮我理解这里发生的事情吗?

Can you please help me understand what is happening here?

已编辑,因为我无法回答8小时之前的问题:

EDITED SINCE I CANNOT ANSWER MY QUESTION BEFORE 8 HRS HAS ELAPSED:

感谢@Andna提出在applicationContext.xml和main-servlet.xml中寻找<context:component-scan />的建议.我在文件中都有该元素,因此每个spring bean都被扫描了两次.

Thanks to @Andna for the suggestion to look for the <context:component-scan /> in applicationContext.xml and main-servlet.xml. I had that element in both the file and hence every spring bean was scanned twice.

但是,从applicationContext.xml中删除<context:component-scan />导致我的Spring安全配置中断.更详细地讲,我创建了一个实现org.springframework.security.core.userdetails.UserDetailsService

However, removing the <context:component-scan /> from the applicationContext.xml caused my Spring security configuration to break. To go in more detail I had created a class that implemented org.springframework.security.core.userdetails.UserDetailsService

@Service("userDetailsService") 
public class DuncanUserDetailsServiceImpl implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
}
}

为支持此类,我在applicationContext-security.xml(缩短版本)文件中添加了以下内容:

To support this class I had the following in my applicationContext-security.xml (shortened version) file:

<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
                    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
                    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                    http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">

<beans:bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
      <beans:property name="userDetailsService" ref="userDetailsService"/>
</beans:bean>

<beans:bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager">
    <beans:property name="providers">
        <beans:list>
            <beans:ref local="daoAuthenticationProvider" />
        </beans:list>
    </beans:property>
</beans:bean>

<authentication-manager>
    <authentication-provider user-service-ref="userDetailsService">
        <password-encoder ref= "passwordEncoder">
            <salt-source user-property="userName"/>
        </password-encoder>
     </authentication-provider>
</authentication-manager>

<beans:bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder" />

</beans:beans>

因此,从applicationContext.xml中删除<context: component-scan />导致"userDetailsS​​ervice"对象实例丢失,并且我的日志文件中出现了很多错误.

Therefore removing <context: component-scan /> from the applicationContext.xml caused the "userDetailsService" object instance to go missing and I got tonnes of errors in my log file.

所以我要做的是将组件扫描保持在main-servlet.xml中:

So what I did was I kept my component scan in the main-servlet.xml as it is:

<context:component-scan base-package="com.some.org" >
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
    </context:component-scan>

但是,我使用applicationContext.xml中的排除过滤器编辑了组件扫描,如下所示:

However, I edited the component scan using the exclude filter in the applicationContext.xml as follows:

<context:component-scan base-package="com.bankofamerica" >
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
        <context:exclude-filter type="regex" expression="com.some.org.common.http.HTTPClient" />
    </context:component-scan>

这帮助我实现了两个目标:

This helped me in achieving both the thing:

  1. 确保单例对象确实是单例
  2. 确保Spring安全性像以前一样工作.

谢谢大家的精彩建议.

推荐答案

也许您在applicationContext.xmlmain-servlet.xml中都进行了两次组件扫描,所以Spring两次扫描了带注释的类?

Maybe you have component-scan twice in both applicationContext.xml and main-servlet.xml, so the Spring scans for the annotated classes twice?

这篇关于Spring正在创建多个bean实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆