Spring mvc Springbeans两次初始化-Spring集成
我正在尝试将我的应用程序与Spring集成集成,并体验到我的定制Spring bean被初始化了两次,基本上我看到这些bean上的init方法被调用了两次,一次是在服务器启动期间,第二次是在通过DispatcherServlet发出HTTP请求时 以下是我的web.xml配置:Spring mvc Springbeans两次初始化-Spring集成,spring-mvc,spring-integration,Spring Mvc,Spring Integration,我正在尝试将我的应用程序与Spring集成集成,并体验到我的定制Spring bean被初始化了两次,基本上我看到这些bean上的init方法被调用了两次,一次是在服务器启动期间,第二次是在通过DispatcherServlet发出HTTP请求时 以下是我的web.xml配置: <servlet> <servlet-name>webapp</servlet-name> <servlet-class>org.springf
<servlet>
<servlet-name>webapp</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/servlet-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>webapp</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
网络应用
org.springframework.web.servlet.DispatcherServlet
上下文配置位置
/WEB-INF/servlet-config.xml
1.
网络应用
/*
这是我的servlet-config.xml(已删除名称空间)
包含所有bean定义的自定义文件springbeans-config.xml如上所示导入。
例如,下面的bean定义将被调用两次,在服务器启动期间和通过DispatcherServlet调用HTTP请求时
<bean name="sample" class="com.test.SampleImpl" init-method="init">
<property name="xpathHelper" ref="XPathHelper"/>
<property name="cacheManager" ref="cacheManager"/>
</bean>
想知道我在这里错过了什么。如果您有任何关于这方面的建议/帮助,我们将不胜感激。谢谢
===============================================================
更新-已解决
SpringIntegration示例中的高利贷示例帮助解决了这个问题
以下是更新后的web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:META-INF/spring/applicationContext*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>gateway</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/servlet-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>gateway</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
上下文配置位置
classpath*:META-INF/spring/applicationContext*.xml
org.springframework.web.context.ContextLoaderListener
网关
org.springframework.web.servlet.DispatcherServlet
上下文配置位置
/WEB-INF/spring/servlet-config.xml
1.
网关
/*
更新了servlet-config.xml(删除了名称空间)。删除了导入到bean定义文件以及该文件中的组件扫描和注释配置
根据示例将springbeans-config.xml重命名为applicationContext.xml,但我想这无关紧要。注意,此文件中也没有导入
<context:component-scan base-package="com.test"/>
<context:annotation-config/>
<bean name="sample" class="com.test.SampleImpl" init-method="init">
<property name="xpathHelper" ref="XPathHelper"/>
<property name="cacheManager" ref="cacheManager"/>
</bean>
Spring MVC应用程序通常有两个上下文;servlet上下文和根上下文 通常,将“web”bean(@Controllers、views、Http入站适配器等)放在servlet上下文中,将所有“业务”bean放在根上下文中是一种好的做法 您应该使用上下文加载程序侦听器将bean放入根上下文中,而不是导入bean servlet上下文中的bean可以在根上下文中获取对bean的引用,但反之亦然
首先加载根上下文;文件名并不重要,但是当在
contextConfigLocation
中使用通配符时,您需要小心不要再次拾取servlet上下文配置。您在XML中定义bean,但我注意到您也在使用组件扫描来扫描bean-您的类有任何注释吗?是的,它们有。我只是在这里添加一个bean作为示例。在service activator组件中还有其他自动连接的助手bean,它们位于springbeans-config.xml下。因此,您是否有使用类似@Component
的注释和xml定义的bean?你能给出一个被初始化两次的单一类的完整例子吗?就像@MattR说的,你很可能已经用实例@Component
注释了SampleImpl
,或者两次定义bean的东西。选择一种定义bean的方法。是的,我确认SampleImpl没有用@Component注释。它仅在springbeans-config.xml下定义。感谢您的见解。那么,上面的“更新”配置看起来好吗?基本上,servlet-config.xml包含所有Spring集成组件,如http入站网关、链、路由器、过滤器、服务激活器等。服务激活器所需的所有帮助器bean都位于springbeans-config.xml下。servlet-config.xml和springbeans-config.xml都是相互独立的,因为它们不会以任何方式相互导入;没有进口。这是个人喜好;将所有SI组件放在servlet上下文中可以生成一个漂亮的图(如果使用SI集成图查看器)。有些人将http入站适配器放在servlet上下文中,将流的其余部分(从第一个通道开始)放在根上下文中。在servlet上下文中包含所有SI组件时,我面临的唯一问题是,这些助手bean被初始化两次,一次是在服务器启动期间,第二次是在实际HTTP请求期间。因此,在根上下文下加载的springbeans-config.xml中包含这些bean(由服务激活器引用)会有所帮助。您的最后一条语句是一个很好的观点,它允许我认为即使servlet配置中的SI链也可以在springbeans配置中移动,这样它们就不会在每个HTTP请求上都被初始化。正确吗?servlet上下文不应该在每个请求上都重新加载,它只有在首次加载servlet时才被初始化-一定是发生了其他事情。
<http:inbound-gateway request-channel="inboundChannel" reply-channel="outboundChannel" name="/*" supported-methods="GET, POST, PUT, DELETE" reply-timeout="120000"/>
<int:chain input-channel="inboundChannel">
<int:service-activator ref="clearContext"/>
<int:service-activator ref="gatewayFilter"/>
<int:service-activator ref="audit_logger"/>
<int:service-activator ref="gatewayContextHandler" method="process"/>
</int:chain>
<context:component-scan base-package="com.test"/>
<context:annotation-config/>
<bean name="sample" class="com.test.SampleImpl" init-method="init">
<property name="xpathHelper" ref="XPathHelper"/>
<property name="cacheManager" ref="cacheManager"/>
</bean>