Spring 正在创建多个 bean 实例

2024-06-11

我使用 autowire @Controller 创建了一个名为 RegistrationController 的 Spring 控制器。出于我自己的好奇心,我创建了一个默认构造函数,如下所示,并添加了一条记录器语句:

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

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

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 默认情况下应该是单例对象,并且只需要创建一个实例。但是,正如您从日志文件中看到的,创建了两个实例。不知怎的,我觉得这是不正确的。但我没有确切的答案。

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

<?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 配置文件。

你能帮我理解这里发生了什么吗?

由于我无法在 8 小时内回答我的问题,因此进行了编辑:

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

然而,删除<context:component-scan />applicationContext.xml 导致我的 Spring 安全配置中断。为了更详细地说明,我创建了一个类来实现org.springframework.security.core.userdetails.UserDetailsService

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

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

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

因此去除<context: component-scan />applicationContext.xml 导致“userDetailsS​​ervice”对象实例丢失,并且我的日志文件中出现了大量错误。

所以我所做的是将组件扫描保留在 main-servlet.xml 中,如下所示:

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

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

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

这帮助我实现了这两件事:

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

感谢大家提出的所有精彩建议。


也许您在两者中都进行了两次组件扫描applicationContext.xml and main-servlet.xml,那么Spring会扫描两次带注释的类?

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring 正在创建多个 bean 实例 的相关文章

随机推荐

  • 在 IE 上使用 CKEditor 插件获取选定的文本

    我为 CKEditor 制作了一个插件 但它依赖于当前选定的文本 在 FF 和 Chrome 中我可以使用 var selectedText editor getSelection getNative 但这在 IE 中不起作用 我只能得到
  • 仅 iOS 7 应用程序在启动时崩溃

    我最近将我的 xcode 项目更改为仅支持 iOS 7 而不支持 iOS 5 应用程序启动后进行此更改后 我会在控制台中收到此消息 UICachedDeviceWhiteColor shadowColor unrecognized sele
  • 如何使用 Cerberus 返回自定义规则名称/错误代码?

    正在验证 csv文件 我想以用户习惯的格式给出验证结果 为了利用Cerberus https docs python cerberus org en stable index html 我让用户在一个中定义验证规则 yaml file 架构
  • 从 Angular 2.2.3 升级到 2.4.0

    我刚刚使用以下命令将我的 Angular 项目从 Angular 2 2 3 升级到 2 4 0npm 检查更新 https www npmjs com package npm check updates 使用 angular cli 编译
  • 禁用向下拖动以关闭 showModalBottomSheet

    如何在底部表单模态中禁用 转义向下拖动手势 以便用户可以在模态中进行交互而不会意外关闭模态 下面用实际的模态底部表进行了更新 return showModalBottomSheet context context builder Build
  • 我可以让 C 函数返回任意类型吗?

    我编写了一个解释串行数据 CAN 的函数 当前返回一个浮点数 我希望该函数包含一个参数 其中用户在字符串中指定返回类型 并且该函数返回该类型的值 这只是一个方便的事情 以避免编写共享几乎所有相同代码的多个函数 将 void 指针传递给您想要
  • 获取URL查询字符串参数

    从格式如下的 URL 查询字符串获取参数的 所需代码较少 的方法是什么 www mysite com category subcategory myqueryhash 输出应该是 myqueryhash 我知道这种方法 www mysite
  • 编译器对开关的优化是否与长 if-then-else 链不同?

    假设我在编译时已知 N 个不同的积分值 V 1 到 V N 考虑以下结构 const int x foo switch x case V 1 commands for V 1 which don t change x break case
  • 在 win32 API 应用程序中实现全球化/多语言功能

    我用 Visual C 开发了一个窗口应用程序 Win32 API 我必须在此应用程序中添加多语言功能 任何人都可以指导我如何完成这项任务 Windows 上多语言应用程序的基础是 资源 的使用 资源是附加在可执行文件末尾的块 它仅包含数据
  • 使用 Homebrew 安装 mongodb 时遇到问题

    我正在尝试让 Mongo 运行 我安装了包管理器Homebrew https brew sh 然后我使用了 Mongo 站点上的命令 brew update brew install mongodb 这似乎安装正确 我输入了mongo在新的
  • 嗅探网络请求

    我正在寻找一种方法来嗅探我的 Android 应用程序生成的网络流量 原因是我想检查并发送我在应用程序中使用的第三方跟踪库生成的流量统计数据 因此 我无法使用任何或类似的 我无法访问此跟踪库的http客户端 因此我无法拦截任何请求 我已经看
  • Microsoft.WindowsAzure.Storage 更新至 V8.2.1.0 破坏了我的代码

    我创建了一个 WebJob 将项目放入队列中 这个过程运行得很好 直到我更新Microsoft WindowsAzure 存储 to v8 2 1 0我现在收到这个错误 存储帐户 devstoreaccount1 无效 请确保您的 凭据是正
  • Angular 5 - 加载视图后加载脚本

    我有一个遗留脚本 需要将其包含在我的角度应用程序中 该脚本的特点是它与特定组件相关 并且只有在加载该组件的视图之后才必须加载它 就今天而言 我成功地将它包含在 OnInit 函数中 但有时 并非总是出于某种原因 CLI 会抛出有关它的错误
  • SELECT、SELECT COUNT 和交叉引用表是否可以仅通过一个查询来处理?

    我有一个显示项目列表的页面 每个项目都会显示从 mysqli 数据库检索到的以下数据 Title Subtitle 描述 零件编号 x 中的 1 与该项目相关的照片总数 从项目中随机选择的照片 标签列表 使用分页系统每页显示 6 个项目 由
  • 通过 npm 节点自动化 Git 提交 + 版本控制 + 标记

    我一直试图得到的是 使用 npm version 来更新 package json 并创建一个标签 然后提交我的更改 通过这种方式 我将能够按版本添加标签 自动版本控制并提交信息 我遇到的问题是 当我使用 npm 版本时 它会自动执行标记
  • 为什么快速调用时Python类的id不唯一?

    我正在Python 3 3 3 中做一些事情 我遇到了一些让我困惑的事情 因为据我了解 类每次被调用时都会获得一个新的id 假设您在某个 py 文件中包含以下内容 class someClass pass print someClass p
  • Xcode 在每次启动时修改当前的 CoreData 模型版本

    我正在使用 Xcode 4 6 来处理使用 CoreData 的项目 数据模型现在是版本13 并且使用轻量级迁移 我的问题 每次启动时 Xcode 似乎都会修改 PROJECT xcdatamodeld xccurrentversion 文
  • 没有名为 pyvirtualdisplay 的模块

    我在 python 代码中导入了这个 import time import sys from pyvirtualdisplay import Display from selenium import webdriver 当我从 centos
  • 如何在 PowerShell 中获取当前活动/前台窗口

    我知道这可以通过使用 alt tab 轻松完成 但创建此脚本的主要目的是自学一些 PowerShell 基础知识 我正在编写一个脚本 运行时会在 powershell 和当前前台窗口之间切换前台窗口 我读这个问题 https stackov
  • Spring 正在创建多个 bean 实例

    我使用 autowire Controller 创建了一个名为 RegistrationController 的 Spring 控制器 出于我自己的好奇心 我创建了一个默认构造函数 如下所示 并添加了一条记录器语句 public Regis