【问题标题】:Spring task:scheduled-tasks bugged?春季任务:计划任务被窃听?
【发布时间】:2015-03-06 08:56:35
【问题描述】:

我发现了以下问题,我想知道这是否是正常行为(如果是,为什么?)或者它是否是 Spring 的错误。我有一个定义计划任务的弹簧上下文文件。如果在我的整个应用程序上下文中多次导入此文件,则该任务也会执行多次。

例如 我有一个上下文文件:a-context.xml:

...
<task:scheduler id="scheduler" pool-size="5"/>

<task:scheduled-tasks scheduler="scheduler">
    <task:scheduled ref="archiveTask" method="run" cron="0 * * * * *"/>
</task:scheduled-tasks>

<bean id="archiveTask" class="ch.post.ehealth.referral.core.task.ArchiveTask" />
...

假设我也有这个 b-context.xml:

...
<import resource="classpath:./a-context.xml" />
...

最后是我的 application-context.xml:

...
<import resource="classpath:./a-context.xml" />
<import resource="classpath:./b-context.xml" />
...

在这种情况下,我的任务被执行了两次,因为它被“导入”了两次。如果我在 application-context.xml 中移动 task:scheduled-tasks 部分,那么它只会按预期执行一次。这是正常的,如果是,为什么? 我不明白,因为 bean 的行为不同。例如。这种情况不会对只创建一次的 bean 造成问题。

谢谢

更新
我的 web.xml:

...
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/application-context.xml</param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-   class>
</listener>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.gwtrpcspring.RemoteServiceDispatcher</servlet-class>
</servlet>
...

【问题讨论】:

  • 如果它被执行两次,你的上下文被加载两次。您可能在ContextLoaderListenerDispatcherServlet 中都加载了a-contxt.xml,它们都在创建自己的ApplicationContext,因此每个都安排执行。这种行为与 bean 没有什么不同,你最终会得到多个实例。
  • 不,事实并非如此。我不使用 DispatcherServlet 仅应用程序上下文加载任何上下文。正如所说的将计划任务的定义从上下文移动到应用程序上下文解决了这个问题
  • 您知道DispatcherServlet 默认加载一个名为[servlet-name]-servlet.xml 的xml 文件。只有当 xml 文件由于某种原因被加载两次时才会出现这种情况,在所有其他情况下,它不会发生,因为 bean 会相互覆盖。
  • 是的,我知道这一点,我没有 [servlet-name]-servlet.xml,因为只有 application-context
  • 如果不看东西是如何加载的,就不可能说出来。如前所述,导入并不重要,因为它们相互覆盖。只有文件加载两次才会出现这种情况。

标签: java spring scheduled-tasks scheduler


【解决方案1】:

在下面的代码中,“application-context.xml”被加载。在 appication-context.xml 中,您已经导入了 a.context 两次。这意味着它已经加载了两次,所以我们的调度器也将被触发两次。如果 bean xml 已经加载,spring 仍然无法避免,然后避免第二次加载它。所以我们在导入的时候一定要小心,尤其是在我们使用调度器的时候。

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/application-context.xml</param-value>
</context-param>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-28
    • 1970-01-01
    • 2019-05-18
    • 2012-06-23
    • 1970-01-01
    相关资源
    最近更新 更多