Jörn Jörn - 1 month ago 14
Java Question

How to combine @Scheduled with Profiles

I've got a class that Spring finds via component scan and that has a method annotated with

@Scheduled
:

@Component
public class Foo {
...
@Scheduled(fixedDelay = 60000)
public void update() {
...


The value
60000
is ok for production, but in my tests I want it to be
1000
.

How can I achieve that? E.g., can I combine
@Scheduled
with profiles somehow?

Answer

I solved this issue like this:

<?xml version="1.0" encoding="UTF-8"?>
<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.2.xsd ...>

<!-- Everything for "default" profile, including the bean with "@Scheduled(fixedDelay = 60000)" on UpdaterTracker.update() and the "taskScheduler" bean -->
...

<!-- Activate this profile in Arquillian tests -->
<beans profile="arquillian">
    <!-- Update more frequently -->
    <bean id="updaterTracker" class="com.foo.UpdaterTracker"/>
    <task:scheduled-tasks scheduler="taskScheduler">
        <task:scheduled ref="updaterTracker" method="update" fixed-delay="1000"/>
    </task:scheduled-tasks>
</beans>

</beans>

The first part defines the beans as usual, including an instance of the UpdaterTracker-bean that performs update() every 60 seconds. The last part is only activated in case "arquillian" profile is active, defining another instance of the UpdaterTracker-bean and a scheduled task that executes update() every second.

The solution is not perfect, because it produces 2 instances of UpdaterTracker and 3 scheduled tasks. It could be optimized by directly referencing the first UpdaterTracker instance in so that we get 1 instance and 2 scheduled tasks.

However, this works for me and the solution has advantages: It does not require additional beans to be coded and can cope with multiple profiles.