为什么 Spring 不运行我的 @Scheduled 方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6154741/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why isn't Spring running my @Scheduled method?
提问by stevevls
I'm a bit befuddled because I'm trying use use @Scheduledannotations, but Spring doesn't seem to be finding my methods. The end result is that, none of my methods annotated with @Scheduledare being executed.
我有点困惑,因为我正在尝试使用 use@Scheduled注释,但 Spring 似乎没有找到我的方法。最终结果是,我的所有注释方法@Scheduled都没有被执行。
I have invoked Spring's task magic with the following declarations:
我使用以下声明调用了 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>
And I have an interface that looks something like this:
我有一个看起来像这样的界面:
package com.mypackage;
public interface MyInterface {
public void executePeriodically();
}
With a corresponding impl like this:
使用这样的相应实现:
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());
}
}
Now the expected result is that I have a very noisy little guy telling me what time it is every 5 seconds...but in reality I get absolutely nothing. I've tried with the annotation on the interface method and on the impl method, but that doesn't seem to change anything.
现在预期的结果是我有一个非常吵闹的小家伙每 5 秒告诉我几点……但实际上我什么也没得到。我已经尝试在接口方法和 impl 方法上使用注释,但这似乎并没有改变任何东西。
I know for sure that the executor and scheduler are being initialized because I have the following in my log:
我确信正在初始化执行程序和调度程序,因为我的日志中有以下内容:
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)
I'm not sure if that line about not being eligible is relevant or a red herring.
我不确定关于不符合条件的那条线是相关的还是红鲱鱼。
At the moment, I'm working around it by declaring my scheduled tasks like so:
目前,我正在通过像这样声明我的计划任务来解决它:
<task:scheduled-tasks>
<task:scheduled ref="sourceDocumentManagerImpl" method="deleteOldDocuments" cron="0 0 * * * ?"/>
</task:scheduled-tasks>
While this works perfectly fine, I'd much rather use the annotations because it's so much more convenient to see directly in the code what the expectations are for that method. Anyone know what I could be doing wrong? For the record, I'm using Spring 3.0.4
虽然这工作得很好,但我更愿意使用注释,因为直接在代码中查看该方法的期望值要方便得多。有谁知道我可能做错了什么?为了记录,我使用的是 Spring 3.0.4
Thanks a bunch!
谢谢一堆!
采纳答案by stevevls
So...it looks like there's a problem in Spring 3.0.x (at the very least 3.0.4 and 3.0.5) having to do with discovering @Scheduledannotations on AOP proxies. I've got a pointcut declaration wrapping the @Scheduledmethod with transactional advice, and that seems to be the root of the problem. If I remove the advice, the job runs. If I add it back in, Spring fails to find and create a task for my annotated method.
所以......看起来Spring 3.0.x(至少3.0.4和3.0.5)中存在一个问题,与发现@ScheduledAOP代理上的注释有关。我有一个切入点声明@Scheduled用事务性建议包装方法,这似乎是问题的根源。如果我删除建议,作业就会运行。如果我重新添加它,Spring 将无法为我的带注释的方法找到并创建任务。
So, I'm going to go file a bug with the Spring folks, and in the meantime I'm stuck declaring my tasks manually.
所以,我要去向 Spring 的人提交一个错误,同时我被困在手动声明我的任务中。
回答by ahll
add "task:annotation-driven" ?
添加“任务:注释驱动”?
<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>
reference http://howtodoinjava.com/2013/04/23/4-ways-to-schedule-tasks-in-spring-3-scheduled-example/
参考http://howtodoinjava.com/2013/04/23/4-ways-to-schedule-tasks-in-spring-3-scheduled-example/
or
或者
Spring @Configuration (non-xml configuration) for annotation-driven tasks
用于注解驱动任务的 Spring @Configuration(非 xml 配置)
Just add @EnableScheduling on you WebMvcConfig class
只需在 WebMvcConfig 类上添加 @EnableScheduling
@Configuration
@EnableWebMvc
@EnableAsync
@EnableScheduling
public class WebMvcConfig extends WebMvcConfigurerAdapter {
/** Annotations config Stuff ... **/
}
reference Spring Scheduler does not work
回答by Hazhir
In spite of that I am using Spring 3.1.2, I am running into the same problem in case i place my executor and scheduler tag in ApplicationContext.xml. i have two xml configuration file for spring in my project which are :
尽管我使用的是 Spring 3.1.2,但如果我将执行程序和调度程序标记放在 ApplicationContext.xml 中,我会遇到同样的问题。我的项目中有两个用于 spring 的 xml 配置文件,它们是:
- applicationContext.xml
- dispatcher-servlet.xml
- 应用上下文.xml
- 调度程序-servlet.xml
So try to move your configuration to the last configuration file which spring reads. in my case it is start working by moving my configuration to dispatcher-servlet.xml
因此,尝试将您的配置移动到 spring 读取的最后一个配置文件。在我的情况下,它通过将我的配置移动到 dispatcher-servlet.xml 开始工作
here is my example:
这是我的例子:
applicationContext.xml
应用上下文.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>
dispatcher-servlet.xml
调度程序-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>
hope it helps.
希望能帮助到你。
回答by Aman Ghrera
I fixed it by adding default-lazy-init="false" to my applicationContext.xml.
我通过将 default-lazy-init="false" 添加到我的 applicationContext.xml 来修复它。
<beans .....
**default-lazy-init="false"**>
回答by Bozho
The only difference that I see from my setup (which works), is that my class is annotated with @Componentrather than @Service. Other things to check:
我从我的设置(有效)中看到的唯一区别是,我的类使用@Component而不是@Service. 其他检查事项:
- whether you have the proper jars on the classpath (spring-context, I think)
- put a breakpoint and check whether it really isn't executing
- double-check the cron expression (I admit I always consult the docs for that). Or use a fixed delay, just to check if it works
- try upgrading to 3.0.5 or the latest 3.1 snapshot.
- 你是否在类路径上有合适的罐子(我认为是弹簧上下文)
- 放置一个断点并检查它是否真的没有执行
- 仔细检查 cron 表达式(我承认我总是为此查阅文档)。或者使用固定延迟,只是为了检查它是否有效
- 尝试升级到 3.0.5 或最新的 3.1 快照。
回答by user2416625
I Solve it by remove use-default-filters="false" in context:component-scan my old config is
我通过在上下文中删除 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>
my spring version 3.2.3
我的 spring 版本 3.2.3
回答by nabeel
This is pretty old question but since this keeps up coming in google search results let me add the solution that worked for me in Spring 5. For me it didn't work until I added @Componentto the class having @Scheduledannotated methods.
这是一个很老的问题,但由于这在 google 搜索结果中不断出现,让我添加了在 Spring 5 中对我有用的解决方案。对我来说,直到我添加@Component到具有@Scheduled注释方法的类中它才起作用。
回答by Mike
I solved by adding both:
我通过添加两者来解决:
xmlns:task="http://www.springframework.org/schema/task"
xmlns:tx="http://www.springframework.org/schema/tx"
then:
然后:
<!-- TASK -->
<task:scheduler id="searchScheduler" pool-size="1"/>
<task:executor id="searchExecutor" pool-size="1"/>
<task:annotation-driven executor="searchExecutor" scheduler="searchScheduler"/>
and in the bootom of my applicationContext.xml:
并在我的 applicationContext.xml 的 bootom 中:
<tx:annotation-driven/>

