Spring bean初始化两次 - Spring Integration

时间:2013-08-16 03:55:34

标签: spring-mvc spring-integration

我正在尝试将我的应用程序与Spring Integration集成,并且体验到我的自定义spring bean正在初始化两次,基本上我看到这些bean上的init方法被调用两次,一次是在服务器启动期间,第二次是HTTP请求是通过DispatcherServlet完成的。

这是我的web.xml配置:

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

这是我的servlet-config.xml(删除了名称空间)

<import resource="springbeans-config.xml"/>

<context:component-scan base-package="com.test"/>

<context:annotation-config/>

<int:channel id="inboundChannel"/>
<int:channel id="outboundChannel"/>

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

导入包含所有bean定义的自定义文件springbeans-config.xml,如上所示。 对于例如在服务器启动期间以及通过DispatcherServlet调用HTTP请求时,下面的bean定义将被调用两次。

    <bean name="sample" class="com.test.SampleImpl" init-method="init">
    <property name="xpathHelper" ref="XPathHelper"/>
    <property name="cacheManager" ref="cacheManager"/>
</bean>

想知道我在这里缺少什么。非常感谢任何指针/帮助。感谢。

=============================================== ================

更新 - 已解决

SpringIntegration示例中的loanhark示例帮助解决了这个问题。

这是更新的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>

更新了servlet-config.xml(删除了名称空间)。删除了此文件中对bean定义文件以及component-scan和annotation-config的导入。

    

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

根据示例将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>

1 个答案:

答案 0 :(得分:5)

Spring MVC Apps通常有2个上下文; servlet上下文和根上下文。

将“web”bean(@Controllers,views,Http inbound adatpers等)放在servlet上下文和根上下文中的所有“business”bean中通常是一种好习惯。

您应该使用上下文加载器侦听器将它们放在根上下文中,而不是导入bean。

servlet上下文中的Bean可以在根上下文中获取对bean的引用,但反之亦然。

首先加载根上下文;文件名无关紧要,但在contextConfigLocation中使用通配符时,需要注意不要再次拾取servlet上下文配置。