|
|
|
|
@@ -463,7 +463,7 @@ shown in this example:
|
|
|
|
|
<entry key="/remoting/AccountService" value-ref="accountExporter"/>
|
|
|
|
|
</util:map>
|
|
|
|
|
</property>
|
|
|
|
|
<property name="port" value="8080" />
|
|
|
|
|
<property name="port" value="8080"/>
|
|
|
|
|
</bean>
|
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
@@ -2061,13 +2061,13 @@ containers that ships with Spring (in this case the `DefaultMessageListenerConta
|
|
|
|
|
[subs="verbatim,quotes"]
|
|
|
|
|
----
|
|
|
|
|
<!-- this is the Message Driven POJO (MDP) -->
|
|
|
|
|
<bean id="messageListener" class="jmsexample.ExampleListener" />
|
|
|
|
|
<bean id="messageListener" class="jmsexample.ExampleListener"/>
|
|
|
|
|
|
|
|
|
|
<!-- and this is the message listener container -->
|
|
|
|
|
<bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
|
|
|
|
|
<property name="connectionFactory" ref="connectionFactory"/>
|
|
|
|
|
<property name="destination" ref="destination"/>
|
|
|
|
|
**<property name="messageListener" ref="messageListener" />**
|
|
|
|
|
**<property name="messageListener" ref="messageListener"/>**
|
|
|
|
|
</bean>
|
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
@@ -2163,7 +2163,7 @@ POJO that we will make into an MDP via the following configuration.
|
|
|
|
|
<bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
|
|
|
|
|
<property name="connectionFactory" ref="connectionFactory"/>
|
|
|
|
|
<property name="destination" ref="destination"/>
|
|
|
|
|
**<property name="messageListener" ref="messageListener" />**
|
|
|
|
|
**<property name="messageListener" ref="messageListener"/>**
|
|
|
|
|
</bean>
|
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
@@ -5930,49 +5930,37 @@ behavior, it is possible to use this abstraction for your own needs.
|
|
|
|
|
==== TaskExecutor types
|
|
|
|
|
|
|
|
|
|
There are a number of pre-built implementations of `TaskExecutor` included with the
|
|
|
|
|
Spring distribution. In all likelihood, you shouldn't ever need to implement your own.
|
|
|
|
|
Spring distribution. In all likelihood, you should never need to implement your own.
|
|
|
|
|
The common out-of-the-box variants are:
|
|
|
|
|
|
|
|
|
|
* `SyncTaskExecutor`
|
|
|
|
|
This implementation does not execute invocations asynchronously. Instead, each
|
|
|
|
|
invocation takes place in the calling thread. It is primarily used in situations
|
|
|
|
|
where multi-threading is not necessary such as in simple test cases.
|
|
|
|
|
* `SimpleAsyncTaskExecutor`
|
|
|
|
|
This implementation does not reuse any threads, rather it starts up a new thread
|
|
|
|
|
for each invocation. However, it does support a concurrency limit which will block
|
|
|
|
|
any invocations that are over the limit until a slot has been freed up. If you
|
|
|
|
|
are looking for true pooling, see the discussions of `SimpleThreadPoolTaskExecutor`
|
|
|
|
|
and `ThreadPoolTaskExecutor` below.
|
|
|
|
|
* `SyncTaskExecutor`
|
|
|
|
|
This implementation doesn't execute invocations asynchronously. Instead, each
|
|
|
|
|
invocation takes place in the calling thread. It is primarily used in situations
|
|
|
|
|
where multi-threading isn't necessary such as simple test cases.
|
|
|
|
|
are looking for true pooling, see `ThreadPoolTaskExecutor` below.
|
|
|
|
|
* `ConcurrentTaskExecutor`
|
|
|
|
|
This implementation is an adapter for a `java.util.concurrent.Executor` object.
|
|
|
|
|
This implementation is an adapter for a `java.util.concurrent.Executor` instance.
|
|
|
|
|
There is an alternative, `ThreadPoolTaskExecutor`, that exposes the `Executor`
|
|
|
|
|
configuration parameters as bean properties. It is rare to need to use the
|
|
|
|
|
`ConcurrentTaskExecutor`, but if the `ThreadPoolTaskExecutor` isn't flexible
|
|
|
|
|
enough for your needs, the `ConcurrentTaskExecutor` is an alternative.
|
|
|
|
|
* `SimpleThreadPoolTaskExecutor`
|
|
|
|
|
This implementation is actually a subclass of Quartz's `SimpleThreadPool` which
|
|
|
|
|
listens to Spring's lifecycle callbacks. This is typically used when you have a
|
|
|
|
|
thread pool that may need to be shared by both Quartz and non-Quartz components.
|
|
|
|
|
configuration parameters as bean properties. There is rarely a need to use
|
|
|
|
|
`ConcurrentTaskExecutor` directly, but if the `ThreadPoolTaskExecutor` is not
|
|
|
|
|
flexible enough for your needs, then `ConcurrentTaskExecutor` is an alternative.
|
|
|
|
|
* `ThreadPoolTaskExecutor`
|
|
|
|
|
This implementation is the most commonly used one. It exposes bean properties for
|
|
|
|
|
configuring a `java.util.concurrent.ThreadPoolExecutor` and wraps it in a `TaskExecutor`.
|
|
|
|
|
If you need to adapt to a different kind of `java.util.concurrent.Executor`, it is
|
|
|
|
|
recommended that you use a `ConcurrentTaskExecutor` instead.
|
|
|
|
|
* `WorkManagerTaskExecutor`
|
|
|
|
|
|
|
|
|
|
+
|
|
|
|
|
|
|
|
|
|
****
|
|
|
|
|
CommonJ is a set of specifications jointly developed between BEA and IBM. These
|
|
|
|
|
specifications are not Java EE standards, but are standard across BEA's and IBM's
|
|
|
|
|
Application Server implementations.
|
|
|
|
|
****
|
|
|
|
|
|
|
|
|
|
+
|
|
|
|
|
|
|
|
|
|
This implementation uses the CommonJ `WorkManager` as its backing implementation and is
|
|
|
|
|
the central convenience class for setting up a CommonJ `WorkManager` reference in a Spring
|
|
|
|
|
context. Similar to the `SimpleThreadPoolTaskExecutor`, this class implements the
|
|
|
|
|
`WorkManager` interface and therefore can be used directly as a `WorkManager` as well.
|
|
|
|
|
This implementation uses a CommonJ `WorkManager` as its backing service provider
|
|
|
|
|
and is the central convenience class for setting up CommonJ-based thread pool
|
|
|
|
|
integration on WebLogic/WebSphere within a Spring application context.
|
|
|
|
|
* `DefaultManagedTaskExecutor`
|
|
|
|
|
This implementation uses a JNDI-obtained `ManagedExecutorService` in a JSR-236
|
|
|
|
|
compatible runtime environment such as a Java EE 7+ application server,
|
|
|
|
|
replacing a CommonJ WorkManager for that purpose.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[scheduling-task-executor-usage]]
|
|
|
|
|
@@ -6000,7 +5988,6 @@ out a set of messages.
|
|
|
|
|
public void run() {
|
|
|
|
|
System.out.println(message);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private TaskExecutor taskExecutor;
|
|
|
|
|
@@ -6014,7 +6001,6 @@ out a set of messages.
|
|
|
|
|
taskExecutor.execute(new MessagePrinterTask("Message" + i));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
@@ -6029,13 +6015,13 @@ been exposed.
|
|
|
|
|
[subs="verbatim,quotes"]
|
|
|
|
|
----
|
|
|
|
|
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
|
|
|
|
|
<property name="corePoolSize" value="5" />
|
|
|
|
|
<property name="maxPoolSize" value="10" />
|
|
|
|
|
<property name="queueCapacity" value="25" />
|
|
|
|
|
<property name="corePoolSize" value="5"/>
|
|
|
|
|
<property name="maxPoolSize" value="10"/>
|
|
|
|
|
<property name="queueCapacity" value="25"/>
|
|
|
|
|
</bean>
|
|
|
|
|
|
|
|
|
|
<bean id="taskExecutorExample" class="TaskExecutorExample">
|
|
|
|
|
<constructor-arg ref="taskExecutor" />
|
|
|
|
|
<constructor-arg ref="taskExecutor"/>
|
|
|
|
|
</bean>
|
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
@@ -6054,16 +6040,25 @@ with a variety of methods for scheduling tasks to run at some point in the futur
|
|
|
|
|
|
|
|
|
|
ScheduledFuture schedule(Runnable task, Trigger trigger);
|
|
|
|
|
|
|
|
|
|
ScheduledFuture schedule(Runnable task, Instant startTime);
|
|
|
|
|
|
|
|
|
|
ScheduledFuture schedule(Runnable task, Date startTime);
|
|
|
|
|
|
|
|
|
|
ScheduledFuture scheduleAtFixedRate(Runnable task, Instant startTime, Duration period);
|
|
|
|
|
|
|
|
|
|
ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period);
|
|
|
|
|
|
|
|
|
|
ScheduledFuture scheduleAtFixedRate(Runnable task, Duration period);
|
|
|
|
|
|
|
|
|
|
ScheduledFuture scheduleAtFixedRate(Runnable task, long period);
|
|
|
|
|
|
|
|
|
|
ScheduledFuture scheduleWithFixedDelay(Runnable task, Instant startTime, Duration delay);
|
|
|
|
|
|
|
|
|
|
ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay);
|
|
|
|
|
|
|
|
|
|
ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay);
|
|
|
|
|
ScheduledFuture scheduleWithFixedDelay(Runnable task, Duration delay);
|
|
|
|
|
|
|
|
|
|
ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay);
|
|
|
|
|
}
|
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
@@ -6077,8 +6072,8 @@ much more flexible.
|
|
|
|
|
[[scheduling-trigger-interface]]
|
|
|
|
|
==== Trigger interface
|
|
|
|
|
|
|
|
|
|
The `Trigger` interface is essentially inspired by JSR-236, which, as of Spring 3.0, has
|
|
|
|
|
not yet been officially implemented. The basic idea of the `Trigger` is that execution
|
|
|
|
|
The `Trigger` interface is essentially inspired by JSR-236 which, as of Spring 3.0,
|
|
|
|
|
was not yet officially implemented. The basic idea of the `Trigger` is that execution
|
|
|
|
|
times may be determined based on past execution outcomes or even arbitrary conditions.
|
|
|
|
|
If these determinations do take into account the outcome of the preceding execution,
|
|
|
|
|
that information is available within a `TriggerContext`. The `Trigger` interface itself
|
|
|
|
|
@@ -6090,7 +6085,6 @@ is quite simple:
|
|
|
|
|
public interface Trigger {
|
|
|
|
|
|
|
|
|
|
Date nextExecutionTime(TriggerContext triggerContext);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
@@ -6109,7 +6103,6 @@ default). Here you can see what methods are available for `Trigger` implementati
|
|
|
|
|
Date lastActualExecutionTime();
|
|
|
|
|
|
|
|
|
|
Date lastCompletionTime();
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
@@ -6144,19 +6137,21 @@ could be configured externally and therefore easily modified or extended.
|
|
|
|
|
==== TaskScheduler implementations
|
|
|
|
|
|
|
|
|
|
As with Spring's `TaskExecutor` abstraction, the primary benefit of the `TaskScheduler`
|
|
|
|
|
is that code relying on scheduling behavior need not be coupled to a particular
|
|
|
|
|
scheduler implementation. The flexibility this provides is particularly relevant when
|
|
|
|
|
running within Application Server environments where threads should not be created
|
|
|
|
|
directly by the application itself. For such cases, Spring provides a
|
|
|
|
|
`TimerManagerTaskScheduler` that delegates to a CommonJ TimerManager instance, typically
|
|
|
|
|
configured with a JNDI-lookup.
|
|
|
|
|
arrangement is that an application's scheduling needs are decoupled from the deployment
|
|
|
|
|
environment. This abstraction level is particularly relevant when deploying to an
|
|
|
|
|
application server environment where threads should not be created directly by the
|
|
|
|
|
application itself. For such scenarios, Spring provides a `TimerManagerTaskScheduler`
|
|
|
|
|
delegating to a CommonJ TimerManager on WebLogic/WebSphere as well as a more recent
|
|
|
|
|
`DefaultManagedTaskScheduler` delegating to a JSR-236 `ManagedScheduledExecutorService`
|
|
|
|
|
in a Java EE 7+ environment, both typically configured with a JNDI lookup.
|
|
|
|
|
|
|
|
|
|
A simpler alternative, the `ThreadPoolTaskScheduler`, can be used whenever external
|
|
|
|
|
thread management is not a requirement. Internally, it delegates to a
|
|
|
|
|
`ScheduledExecutorService` instance. `ThreadPoolTaskScheduler` actually implements
|
|
|
|
|
Spring's `TaskExecutor` interface as well, so that a single instance can be used for
|
|
|
|
|
asynchronous execution __as soon as possible__ as well as scheduled, and potentially
|
|
|
|
|
recurring, executions.
|
|
|
|
|
Whenever external thread management is not a requirement, a simpler alternative is
|
|
|
|
|
a local `ScheduledExecutorService` setup within the application which can be adapted
|
|
|
|
|
through Spring's `ConcurrentTaskScheduler`. As a convenience, Spring also provides a
|
|
|
|
|
`ThreadPoolTaskScheduler` which internally delegates to a `ScheduledExecutorService`,
|
|
|
|
|
providing common bean-style configuration along the lines of `ThreadPoolTaskExecutor`.
|
|
|
|
|
These variants work perfectly fine for locally embedded thread pool setups in lenient
|
|
|
|
|
application server environments as well, in particular on Tomcat and Jetty.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -7377,8 +7372,7 @@ Alternatively for XML configuration use the `cache:annotation-driven` element:
|
|
|
|
|
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
|
|
|
|
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
|
|
|
|
|
|
|
|
|
|
<cache:annotation-driven />
|
|
|
|
|
|
|
|
|
|
<cache:annotation-driven/>
|
|
|
|
|
</beans>
|
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
|