I have a problem with Spring's annotation based task scheduler - I can't get it working, I don't see any problem here...
application-context.xml
<task:scheduler id="taskScheduler" />
<task:executor id="taskExecutor" pool-size="1" />
<task:annotation-driven executor="taskExecutor" scheduler="taskScheduler" />
bean
#Service
public final class SchedulingTest {
private static final Logger logger = Logger.getLogger(SchedulingTest.class);
#Scheduled(fixedRate = 1000)
public void test() {
logger.debug(">>> Scheduled test service <<<");
}
}
Spring #Configuration (non-xml configuration) for annotation-driven tasks
Just add #EnableScheduling on your WebMvcConfig class
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
#Configuration
#EnableWebMvc
#EnableAsync
#EnableScheduling
public class WebMvcConfig implements WebMvcConfigurer {
/** Annotations config Stuff ... **/
}
If you want to use task:annotation-driven approach and your #Scheduled annotation is not working, then you most probably missed context:component-scan in your context xml.
Without this line, spring cannot guess where to search for your annotations.
<context:component-scan base-package="..." />
This is happening because by default Spring lazy initializes the beans.
Disable lazy initialization for the bean by placing this annotation
#Lazy(false)
on top of your #Component.
For me the solution that worked in Spring 5 was that I had to add #Component to the class having #Scheduled annotated methods.
After configuring the Schedulers, add #EnableScheduling in your main class.
I finally found a solution.
application-context.xml
<bean id="schedulingTest" class="...SchedulingTest" />
<task:scheduled-tasks>
<task:scheduled ref="schedulingTest" method="test" cron="* * * * * ?"/>
</task:scheduled-tasks>
and the test() method without the annotation. This runs the method every second and works perfectly.
if you have dispatcher-servlet.xml move your configuration there. it worked for me and i have left a comment in this article:
https://stackoverflow.com/a/11632536/546130
The solution for me was to add in the applicationContext.xml:
<task:annotation-driven/>
with the following schemaLocation:
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd
You should also check lazy-init to be false for that bean or use default-lazy-init="false" in beans.
That solved my problem.
I had to update my dispatcher-servlet.xml with
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-4.3.xsd"></beans>
Bean definition below:
<bean id="scheduledTasks" class="com.vish.services.scheduler.ScheduledTasks"></bean>
We had the following reason:
Service needed an interface (due to Transaction annotation) - IDE added this tx annotation also to interface. But #Scheduled was in implementing service class - and Spring ignored it since it thought that only annotations exist on the interface. So be careful to only have annotations on implementing classes!
Just add #EnableScheduling at any spring boot configuration class annotated with #Configuration and for the method that run the schedule job add #Scheduled annotation.
Maybe it will be useful for someone. I ran into similar issue when I had a bean that did a long processing job in PostConstruct method. Thus, Spring Boot application didn't start (because PostConstruct method was in progress) and that's why my scheduled jobs didn't run (they start running after application startup).
If you are using Grails with Spring Scheduler you will need to add to the top of your class.
static lazyInit = false
Source
I have defined various scheduler in my configuration file as follows:
<task:executor id="xxxxxExecutor" pool-size="${async.executor.pool.size}"/>
<task:scheduler id="xxxxwwwScheduler" pool-size="1" />
<task:scheduler id="qqqqSchedular" pool-size="1" />
<task:scheduler id="lastScheduler" pool-size="1" />
My controller has been annotated via #Controller annotation. How do I specify a particular Scheduler in #Scheduled annotation in Spring?
p.s. I am trying to schedule a method in a controller using #Scheduled annotation.
Using multiple schedulers and pointing to them via the #Scheduled annotation is unfortunately not possible.
However, if you really do need that flexibility, you can define the jobs in XML:
<task:scheduled-tasks scheduler="myScheduler">
<task:scheduled ref="beanA" method="methodA" fixed-delay="5000"/>
</task:scheduled-tasks>
That allows you to specify the exact id of the scheduler you need to use, and then simply reference the actual task.
Hope this helps.
I am using annotation based scheduler like #Scheduled(fixedDelay = 1200000)
and I want to pass information like langId , loginUserId etc.
I have a scheduler MyScheduler, I have configured it in .property file as:
<task:annotation-driven />
<bean id="myScheduler" class="ab.abc.txn.service.MyScheduler"></bean>
use <property in bean defination
My problem is that I have a function implemented on my website which searches for Particular Tweet when I press the button. I want it to make it automatic such that, that function is called again and again after every two minutes, regardless some one uses the website or not.. How to do this in java?? Spring Solution is better
You could use Spring scheduling (see documentation here)
From the doc:
XML config
<context:component-scan base-package="some.package" />
<task:annotation-driven executor="myExecutor" scheduler="myScheduler"/>
<task:executor id="myExecutor" pool-size="5"/>
<task:scheduler id="myScheduler" pool-size="10"/>
Java bean
#Component
public class SomeBean {
#Scheduled(fixedRate=5000)
public void doSomething() {
// something that should execute periodically
}
}
25.5.3 The Element
To enable both #Scheduled and #Async annotations, simply include the
'annotation-driven' element from the task namespace in your
configuration.
<task:annotation-driven executor="myExecutor" scheduler="myScheduler"/>
<task:executor id="myExecutor" pool-size="5"/>
<task:scheduler id="myScheduler" pool-size="10"/>
Notice that an executor reference is provided for handling those tasks
that correspond to methods with the #Async annotation, and the
scheduler reference is provided for managing those methods annotated
with #Scheduled.
Is there anyway to do this without XML?
This is possible with the newly-released Spring 3.1, but not 3.0 - See #EnableAsync and #EnableScheduling.
For #Dejel question: (as I am not able to post comment)
It is possible to specify executor for certain task. This can be achieved by specyfing executor name as value of #Async annotation. See:
https://jira.spring.io/browse/SPR-6847
http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/scheduling/annotation/Async.html
http://www.baeldung.com/spring-async