Scheduling in Spring.
Pure annotation
based approach.
Let us use pure Java based configuration. No web.xml. No
Spring configuration xml.
I am going to use maven to create a project for me
eclipse.
Here are my dependencies from pom.xml
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
Set the packaging as war
<packaging>war</packaging>
Since there is going to be no web.xml, we need to tell this
to maven, so that maven generates the war file for us regardless of the present
of deployment descriptor file. So set <failOnMissingWebXml> to false in
maven-war-plugin configuration.
<build>
<finalName>springscheduler</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.5</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
@Configuration
@ComponentScan(basePackages="com.rizwan.test")
@EnableScheduling
public class
AppConfig {
}
@EnableScheduling annotation enables Spring's scheduled
task execution capability, similar to functionality found in Spring's <task:*>
XML namespace. To be used on @Configuration classes. Without @EnableScheduling @Schedule
annotation would have no effect. It is the xml equivalent of <task:annotation-driven />. Just
as without <task:annotationdriven /> scheduling wont happen, similarly without
@EnableScheduling scheduling won’t happen.
The Java configuration class decorated with
@Configuration annotation. This class eliminates the need for spring
configuration.
Taken straight from Javadoc of @Configuration annotation:
@Configuration Indicates that a class declares one or more @Bean methods and
may be processed by the Spring container to generate bean definitions and
service requests for those beans at runtime.
The AppConfig class here is empty. Note the presence of
@ComponentScan annotation. It configures component scanning for use with
@Configuration. Thus for classes annotated with @Service, @Controller,
@Component, @RESTController, @Repository, etc, a bean will be created
automatically and registered in the spring application context.
public interface Work {
public void work();
}
@Component("synch")
public class
SynchWorker implements Work {
public void work() {
System.out.println("Doing
some work");
}
}
Work interface and its implementation represents a Spring
component for doing any work.
@Service
public interface
RefreshTokenService {
public void refreshToken();
}
@Service
public class
RefreshTokenServiceImpl implements
RefreshTokenService {
@Autowired
@Qualifier("synch")
private SynchWorker worker;
public SynchWorker
getWorker() {
return worker;
}
public void setWorker(SynchWorker
worker) {
this.worker = worker;
}
/*
* fixedDelay -
Execute the annotated method with a fixed period in
* milliseconds
between the end of the last invocation and the start of the
* next.
*
* fixedRate -
Execute the annotated method with a fixed period in
* milliseconds
between invocations.
*
* initialDelay -
Number of milliseconds
* to delay before
the first execution of a fixedRate() or fixedDelay()
* task.
*/
@Scheduled(fixedDelay = 1000, initialDelay = 1000)
public void refreshToken() {
worker.work();
}
}
Note that method decorated with @Scheduled annotation
must return void and must not accept any arguments.
Here the scheduling is happening synchronously. This
means unless the previous task is completed, next run of the task won’t start.
It will simply wait for the previous task to complete.
In the asynchronous scheduling next task will start
irrespective of whether previous task has finished. Next task will be typically
started in a new thread.
For asynchronous scheduling, use the @Async annotation.
@Scheduled(fixedDelay
= 1000, initialDelay = 1000)
@Async
public void refreshToken() {
worker.work();
}
@Scheduled and @Async annotations can be applied on both
refreshToken method of Service class as well as work method of the Worker
component.