Categories: spring

Spring Job Scheduling with @Scheduled & @EnableScheduling Annotations

In this post we will how to Schedule a Job in Spring using Spring @Scheduled and @EnableScheduling Annotations based Configuration. Let’s get going.


Following technologies being used:

  • Spring 4.0.6.RELEASE
  • Maven 3
  • JDK 1.6
  • Eclipse JUNO Service Release 2

Project directory structure:

Following will be the final project directory structure for this example:

Let’s now add the content mentioned in above structure explaining each in detail.

Step 1: Provide Spring dependencies in Maven pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>

 <groupId>com.websystique.spring</groupId>
 <artifactId>SpringSchedulingAnnotationExample</artifactId>
 <version>1.0.0</version>
 <packaging>jar</packaging>
 <name>SpringSchedulingAnnotationExample</name>

 <properties>
  <springframework.version>4.0.6.RELEASE</springframework.version>
 </properties>

 <dependencies>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-core</artifactId>
   <version>${springframework.version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-context</artifactId>
   <version>${springframework.version}</version>
  </dependency>
 </dependencies>
 <build>
  <pluginManagement>
   <plugins>
    <plugin>
     <groupId>org.apache.maven.plugins</groupId>
     <artifactId>maven-compiler-plugin</artifactId>
     <version>3.2</version>
     <configuration>
      <source>1.6</source>
      <target>1.6</target>
     </configuration>
    </plugin>
   </plugins>
  </pluginManagement>
 </build>

</project>

Step 2: Create Spring Configuration Class

Spring configuration class are the ones annotated with @Configuration. These classes contains methods annotated with @Bean. These @Bean annotated methods generates beans managed by Spring container.

package com.websystique.spring.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;

import com.websystique.spring.scheduling.MyBean;

@Configuration
@EnableScheduling
public class AppConfig {

 @Bean
 public MyBean bean() {
  return new MyBean();
 }

}

Notice @EnableScheduling. This annotation enables Spring’s scheduled task execution capability, similar to functionality found in Spring’s task namespace we saw in previous tutorial. Thanks to @EnableScheduling, all the bean methods annotated with @Scheduler will be registered for scheduling

Below is the Bean class itself:


package com.websystique.spring.scheduling;

import org.springframework.scheduling.annotation.Scheduled;

public class MyBean {

 @Scheduled(fixedRate=5000)
 public void printMessage() {
  System.out.println("I am called by Spring scheduler");
 }
}

Above @Scheduled annotated method will be called by Scheduler every 5 seconds. Note that the method which is annotated with @Scheduler must return void and must not have any parameters. Of course you can inject another bean in above bean to get some external functionality called in printMessage.

@Scheduled annotation have several attributes to specify different scheduling timelines. initialDelay attribute specifies the number of milliseconds to wait before the first execution of the method. fixedRate specifies the number of milliseconds between each method start , regardless of how long method takes to complete. fixedDelay specifies the number of milliseconds between completion of previous run, and start of next run.
Attribute cron provides more fine-grained control on task execution scheduling. For example, @Scheduled(cron=*/5 * * * * MON-FRI") configures this method to be executed every 5 seconds but only on weekdays.

Step 3: Create Main and Run it

package com.websystique.spring;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;

import com.websystique.spring.config.AppConfig;

public class AppMain {
 
 @SuppressWarnings({ "unused", "resource" })
 public static void main(String args[]){
  AbstractApplicationContext  context = new AnnotationConfigApplicationContext(AppConfig.class);
 }

}

Note that we are not calling any explicit scheduling class or method here, just registering plain Configuration class. As we have annotated the configuration class with @EnableScheduling, the bean methods annotated with @Scheduler will automatically be registered for scheduling.

Run above program as Java Application, you will see following output

INFO: Bean 'org.springframework.scheduling.annotation.SchedulingConfiguration' of type [class org.springframework.scheduling.annotation.SchedulingConfiguration$$EnhancerBySpringCGLIB$$bcca717e] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
I am called by Spring scheduler
I am called by Spring scheduler
I am called by Spring scheduler
I am called by Spring scheduler
I am called by Spring scheduler
.....

That’s it.

Now, as we discussed in previous post , in case you have tasks which can take long time to complete, and are frequent, you can optionally configure thread-pool with specified pool-size to handle each tasks in separate thread.

Below is the updated Configuration class with thread-pooling included

package com.websystique.spring.config;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;

import com.websystique.spring.scheduling.MyBean;

@Configuration
@EnableScheduling
public class AppConfig implements SchedulingConfigurer {

 @Bean
 public MyBean bean() {
  return new MyBean();
 }

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(taskExecutor());
    }

    @Bean(destroyMethod="shutdown")
    public Executor taskExecutor() {
        return Executors.newScheduledThreadPool(10);
    }

}

Above we have configured the scheduler with thread-pool of 10 threads.

Running main program with above changes provides same output, with additional thread-pool support.

Download Source Code


References

Share
Published by

Recent Posts

Spring Boot + AngularJS + Spring Data + JPA CRUD App Example

In this post we will be developing a full-blown CRUD application using Spring Boot, AngularJS, Spring Data, JPA/Hibernate and MySQL,…

8 years ago

Spring Boot Rest API Example

Spring Boot complements Spring REST support by providing default dependencies/converters out of the box. Writing RESTful services in Spring Boot…

8 years ago

Spring Boot WAR deployment example

Being able to start the application as standalone jar is great, but sometimes it might not be possible to run…

8 years ago

Spring Boot Introduction + hello world example

Spring framework has taken the software development industry by storm. Dependency Injection, rock solid MVC framework, Transaction management, messaging support,…

8 years ago

Secure Spring REST API using OAuth2

Let's secure our Spring REST API using OAuth2 this time, a simple guide showing what is required to secure a…

8 years ago

AngularJS+Spring Security using Basic Authentication

This post shows how an AngularJS application can consume a REST API which is secured with Basic authentication using Spring…

8 years ago