viernes, 17 de abril de 2015

JAVA - 4 Formas de programar trabajos en Spring 3: @Scheduled con Ejemplo

Spring 3.0 also adds annotation support for both task scheduling and asynchronous method execution. The @Scheduled annotation can be added to a method along with trigger metadata.
In this post, I will show the means to use this feature in 4 different ways.
Sections in this post:

Explaining @Scheduled annotation
Task scheduling using fixed delay attribute in @Scheduled annotation
Task scheduling using cron expression in @Scheduled annotation
Task scheduling using cron expression from properties file and @Scheduled annotation
Task scheduling using cron expression configured in context configuration
Sourcecode download link

Explaining @Scheduled annotation

This annotation is used for task scheduling. The trigger information needs to be provided along with this annotation. You can use the properties fixedDelay/fixedRate/cron to provide the triggering information.
  1. fixedRate makes Spring run the task on periodic intervals even if the last invocation may be still running.
  2. fixedDelay specifically controls the next execution time when the last execution finishes.
  3. cron is a feature originating from Unix cron utility and has various options based on your requirements.
Example usage can be as below:
@Scheduled(fixedDelay =30000)
public void demoServiceMethod () {... }

@Scheduled(fixedRate=30000)
public void demoServiceMethod () {... }

@Scheduled(cron="0 0 * * * *")
public void demoServiceMethod () {... }
To use @Scheduled in your spring application, you must first define below xml namespace and schema location definition in your application-config.xml file.
Above additions are necessary because we will be using annotation based configurations. Now add below definition to enable annotations.
1
<task:annotation-driven>
Next step is to create a class and a method inside the class like below:
1
2
3
4
5
6
7
8
public class DemoService
{
    @Scheduled(cron="*/5 * * * * ?")
    public void demoServiceMethod()
    {
        System.out.println("Method executed at every 5 seconds. Current time is :: "new Date());
    }
}
Using @Scheduled annotation would in turn make Spring container understand that the method underneath this annotation would run as a job.  Remember that the methods annotated with @Scheduled should not have parameters passed to them. They should not return any values too. If you want the external objects to be used within your @Scheduled methods, you should inject them into the DemoService class using autowiring rather than passing them as parameters to the @Scheduled methods.

Method 1) Task scheduling using fixed delay attribute in @Scheduled annotation

In this method, fixedDelay attribute is used with @Scheduled annotation. Alternatively, fixedRate can also be used.
A sample class will look like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.howtodoinjava.service;
import java.util.Date;
import org.springframework.scheduling.annotation.Scheduled;
public class DemoServiceBasicUsageFixedDelay
{
    @Scheduled(fixedDelay = 5000)
    //@Scheduled(fixedRate = 5000)
    public void demoServiceMethod()
    {
        System.out.println("Method executed at every 5 seconds. Current time is :: "new Date());
    }
}
And application configuration will look like this:

Method 2) Task scheduling using cron expression in @Scheduled annotation

In this method, cron attribute is used with @Scheduled annotation. Value of this attribute must be a cron expression.
A sample class will look like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
package com.howtodoinjava.service;
import java.util.Date;
import org.springframework.scheduling.annotation.Scheduled;
public class DemoServiceBasicUsageCron
{
    @Scheduled(cron="*/5 * * * * ?")
    public void demoServiceMethod()
    {
        System.out.println("Method executed at every 5 seconds. Current time is :: "new Date());
    }
}
And application configuration will look like this:

Method 3) Task scheduling using cron expression from properties file 

In this method, cron attribute is used with @Scheduled annotation. Value of this attribute must be a cron expression as in previous method, BUT, this cron expression will be defined in a properties file and key of related property will be used in @Scheduled annotation.
This will decouple the cron expression from source code, thus making changes easy.
A sample class will look like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.howtodoinjava.service;
import java.util.Date;
import org.springframework.scheduling.annotation.Scheduled;
public class DemoServicePropertiesExample {
    @Scheduled(cron = "${cron.expression}")
    public void demoServiceMethod()
    {
        System.out.println("Method executed at every 5 seconds. Current time is :: "new Date());
    }
}
And application configuration will look like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml  version="1.0" encoding="UTF-8"?>
    <task:annotation-driven />
    <util:properties id="applicationProps" location="application.properties" />
    <context:property-placeholder properties-ref="applicationProps" />
    <bean id="demoServicePropertiesExample" class="com.howtodoinjava.service.DemoServicePropertiesExample"></bean>
</beans>

Método 4) La tarea programada usando cron expression configurada en archivo de configuración dentro del contexto de Spring.

En este método, una cron expression es configurada en un archivo .properties, y el job scheduling es configurado en el archivo de configuración usando una property key por cron expression. Lo mejor, es que no se necesita usar el annotation @Scheduled. La configuración solo se hace en el archivo de configuración de la aplicación.
Ejemplo de clase:
1
2
3
4
5
6
7
8
9
10
11
12
package com.howtodoinjava.service;
import java.util.Date;
public class DemoServiceXmlConfig
{
    public void demoServiceMethod()
    {
        System.out.println("Method executed at every 5 seconds. Current time is :: "new Date());
    }
}
y en la aplicación se verá de esta manera:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml  version="1.0" encoding="UTF-8"?>
    <task:annotation-driven />
    <util:properties id="applicationProps" location="application.properties" />
    <context:property-placeholder properties-ref="applicationProps" />
    <bean id="demoServiceXmlConfig" class="com.howtodoinjava.service.DemoServiceXmlConfig" />
    <task:scheduled-tasks>
        <task:scheduled ref="demoServiceXmlConfig" method="demoServiceMethod" cron="#{applicationProps['cron.expression']}"></task:scheduled>
    </task:scheduled-tasks>
</beans>

No hay comentarios.:

Publicar un comentario