为什么Spring不运行我的@Scheduled方法?

时间:2011-05-27 15:54:23

标签: spring annotations scheduler

我有点迷糊,因为我正在尝试使用@Scheduled注释,但Spring似乎没有找到我的方法。最终结果是,没有一个用@Scheduled注释的方法正在被执行。

我使用以下声明调用了Spring的任务魔法:

<beans> <!-- XMLNS, XSD declarations omitted for brevity -->

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

  <task:executor id="executor" pool-size="5"/>
  <task:scheduler id="scheduler" pool-size="5"/>
  <task:annotation-driven scheduler="scheduler" executor="executor"/>

</beans>

我的界面看起来像这样:

package com.mypackage;

public interface MyInterface {

    public void executePeriodically();
}

有这样的相应impl:

package com.mypackage.impl;
// imports omitted for brevity

@Service
public class MyInterfaceImpl implements MyInterface {

    @Scheduled(cron = "0/5 * * * * ?")
    public void executePeriodically() {
        System.out.println("The time is now : " + new Date());
    }
}

现在预期的结果是,我有一个非常吵闹的小家伙告诉我每5秒钟的时间......但实际上我什么都没有。我已尝试使用接口方法和impl方法的注释,但这似乎没有改变任何东西。

我确定已经初始化了执行程序和调度程序,因为我的日志中有以下内容:

INFO  - ThreadPoolTaskExecutor     - Initializing ExecutorService 
INFO  - XmlWebApplicationContext   - Bean 'executor' is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO  - XmlWebApplicationContext   - Bean 'executor' is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO  - ThreadPoolTaskScheduler    - Initializing ExecutorService  'scheduler'
INFO  - XmlWebApplicationContext   - Bean 'scheduler' is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)

我不确定关于不符合条件的那条线是否相关或是否是红鲱鱼。

目前,我正在通过宣布我的预定任务来解决这个问题:

<task:scheduled-tasks>
  <task:scheduled ref="sourceDocumentManagerImpl" method="deleteOldDocuments" cron="0 0 * * * ?"/>
</task:scheduled-tasks>

虽然这很好用,但我更倾向于使用注释,因为直接在代码中看到对该方法的期望是多么方便。谁知道我可能做错了什么?为了记录,我使用的是Spring 3.0.4

非常感谢!

8 个答案:

答案 0 :(得分:15)

添加&#34;任务:注释驱动&#34; ?

<beans> <!-- XMLNS, XSD declarations omitted for brevity -->

  <context:component-scan base-package="com.mypackage"/>
  <task:annotation-driven/>
  <task:executor id="executor" pool-size="5"/>
  <task:scheduler id="scheduler" pool-size="5"/>
  <task:annotation-driven scheduler="scheduler" executor="executor"/>

</beans>

参考http://howtodoinjava.com/2013/04/23/4-ways-to-schedule-tasks-in-spring-3-scheduled-example/

用于注释驱动任务的Spring @Configuration(非xml配置)

只需在WebMvcConfig类

上添加@EnableScheduling即可
@Configuration
@EnableWebMvc
@EnableAsync
@EnableScheduling
public class WebMvcConfig extends WebMvcConfigurerAdapter {
   /** Annotations config Stuff ... **/
}

参考Spring Scheduler does not work

答案 1 :(得分:13)

所以......看起来Spring 3.0.x中存在一个问题(至少3.0.4和3.0.5)与在AOP代理上发现@Scheduled注释有关。我有一个包含事务建议的@Scheduled方法的切入点声明,这似乎是问题的根源。如果我删除了建议,则该作业将运行。如果我重新添加它,Spring无法为我的带注释方法找到并创建任务。

所以,我要向Spring人员提交一个bug,与此同时我不能手动声明我的任务。

答案 2 :(得分:4)

尽管我使用的是Spring 3.1.2,但是如果我将我的executor和scheduler标记放在ApplicationContext.xml中,我遇到了同样的问题。我在我的项目中有两个用于spring的xml配置文件:

  1. 的applicationContext.xml
  2. 调度-servlet.xml中
  3. 因此,请尝试将配置移动到spring读取的最后一个配置文件。在我的情况下,它通过将我的配置移动到dispatcher-servlet.xml

    开始工作

    这是我的例子:

    <强>的applicationContext.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:p="http://www.springframework.org/schema/p"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xmlns:context="http://www.springframework.org/schema/context" 
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xmlns:task="http://www.springframework.org/schema/task"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
           http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
           http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">
    
        <bean id="config" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
            <property name="location" value="/WEB-INF/configuration.properties" />
        </bean>
    
        <!-- To fix the problem with Unicode characters in ajax responses -->
        <bean class = "org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
            <property name="messageConverters">
                <array>
                    <bean class = "org.springframework.http.converter.StringHttpMessageConverter">
                        <property name="supportedMediaTypes" value = "text/plain;charset=UTF-8" />
                    </bean>
                    <bean id="byteArrayMessageConverter" class="org.springframework.http.converter.ByteArrayHttpMessageConverter" />
                </array>
            </property>
        </bean>
    
        <!-- Hibernate Configuration
            p:driverClassName="com.mysql.jdbc.Driver"
            p:url="jdbc:mysql://localhost:3306/iss"
            p:username="root"
            p:password="root"
        -->
        <bean name="DataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"
              p:driverClassName="org.postgresql.Driver"
              p:url="jdbc:postgresql://localhost:5432/iss"
              p:username="postgres"
              p:password=""
    
        />
    
        <!--<bean name="SessionFactory" class="org.springframework.orm.hibernate4.annotation.AnnotationSessionFactoryBean">-->
        <bean name="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
            <property name="dataSource">
                <ref bean="DataSource" />
            </property>
            <property name="hibernateProperties">
                <props>
                    <!--<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>-->
                    <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
                    <prop key="hibernate.hbm2ddl.auto">update</prop>
                    <prop key="hibernate.show_sql">true</prop>
                    <!--<prop key="hibernate.current_session_context_class">thread</prop>-->
                    <!--<prop key="hibernate.current_session_context_class">managed</prop>-->
                    <!--<prop key="hibernate.search.default.indexBase">/tmp/hibernate/indexes/</prop>-->
                    <!--<prop key="hibernate.flushMode">AUTO</prop>-->
                    <prop key="hibernate.connection.useUnicode">true</prop>
                    <prop key="hibernate.connection.characterEncoding">UTF-8</prop>
                    <prop key="hibernate.cache.use_second_level_cache">false</prop>
                    <prop key="hibernate.cache.use_query_cache">false</prop>
                    <prop key="hibernate.connection.autocommit">false</prop>
                </props>
            </property>
            <property name="packagesToScan" value="iss.DB" />
        </bean>
    
        <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
            <property name="sessionFactory" ref="sessionFactory" />
        </bean>
    
        <mvc:interceptors>
            <bean class="org.springframework.orm.hibernate4.support.OpenSessionInViewInterceptor">
                <property name="sessionFactory" ref="sessionFactory" />
            </bean>
        </mvc:interceptors>
    
        <tx:annotation-driven transaction-manager="txManager" proxy-target-class="true"/>
    
    
    <!-- in this file it wont work
            <task:executor id="myExecutor" pool-size="1" />
        <task:scheduler id="myScheduler" pool-size="1" />
        <task:annotation-driven 
            executor="myExecutor"
            scheduler="myScheduler"/>    
    -->
    </beans>
    

    <强>调度-servlet.xml中

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:p="http://www.springframework.org/schema/p"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xmlns:task="http://www.springframework.org/schema/task"
           xsi:schemaLocation="http://www.springframework.org/schema/beans 
           http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
           http://www.springframework.org/schema/aop 
           http://www.springframework.org/schema/aop/spring-aop.xsd
           http://www.springframework.org/schema/tx 
           http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
           http://www.springframework.org/schema/context 
           http://www.springframework.org/schema/context/spring-context-3.1.xsd
           http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd" 
           xmlns:context="http://www.springframework.org/schema/context">
    
        <bean class="org.springframework.web.servlet.mvc.support.AnnotationControllerTypePredicate"/>
    
        <context:component-scan base-package="iss"/>
        <context:component-scan base-package="com.hazhir"/>
    
        <!--Internationalization -->
        <bean id="messageSource"
              class="org.springframework.context.support.ResourceBundleMessageSource">
            <property name="basename" value="iss.languages.text" />
        </bean>
    
        <bean id="localChangeInterseptor"
              class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
            <property name="paramName" value="language" />
        </bean>
    
        <bean id="localeResolver"
              class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
            <property name="defaultLocale" value="en_US" />
            <property name="cookieName" value="clientLanguage" />
            <property name="cookieMaxAge" value="99999999"/>
        </bean>
    
        <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
            <property name="alwaysUseFullPath" value="true" />
            <property name="interceptors">
                <list>
                    <ref bean="localChangeInterseptor" />
                </list>
            </property>
        </bean>
    
        <bean id="viewResolver"
              class="org.springframework.web.servlet.view.InternalResourceViewResolver"
              p:prefix="/WEB-INF/jsp/"
              p:suffix=".jsp">
            <property name="exposeContextBeansAsAttributes" value="true" />
        </bean>
    
        <!-- Multipart form data -->
        <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
            <property name="maxUploadSize" value="1000000000" />
        </bean>
    
        <context:annotation-config />
    
        <!-- here is a right place for such configuration
            -->
        <task:executor id="myExecutor" pool-size="1" />
        <task:scheduler id="myScheduler" pool-size="1" />
        <task:annotation-driven 
            executor="myExecutor"
            scheduler="myScheduler"/> 
    </beans>
    
    希望它有所帮助。

答案 3 :(得分:3)

我通过将default-lazy-init =“false”添加到我的applicationContext.xml来修复它。

<beans .....
    **default-lazy-init="false"**>

答案 4 :(得分:2)

我从我的设置(可行)中看到的唯一区别是,我的课程使用@Component而不是@Service进行了注释。其他要检查的事项:

  • 你是否在类路径上有正确的jar(我认为是spring-context)
  • 设置一个断点并检查它是否真的没有执行
  • 仔细检查cron表达式(我承认我总是查阅文档)。或使用固定延迟,只是为了检查它是否有效
  • 尝试升级到3.0.5或最新的3.1快照。

答案 5 :(得分:1)

我通过在上下文中删除use-default-filters =“false”来解决它:component-scan 我的旧配置是

 <context:component-scan base-package="com.XXXx" use-default-filters="false">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

我的春季版3.2.3

答案 6 :(得分:0)

我通过添加两个来解决:

xmlns:task="http://www.springframework.org/schema/task"
xmlns:tx="http://www.springframework.org/schema/tx"

然后:

<!-- TASK -->
    <task:scheduler id="searchScheduler" pool-size="1"/>
    <task:executor id="searchExecutor" pool-size="1"/>
    <task:annotation-driven executor="searchExecutor"  scheduler="searchScheduler"/>

并在我的applicationContext.xml的bootom中:

<tx:annotation-driven/>

答案 7 :(得分:0)

这是一个非常老的问题,但是由于这个问题不断出现在Google搜索结果中,因此我要添加在春季5时适用于我的解决方案。对我而言,直到我将@Component添加到具有@Scheduled带注释的方法。