From 94d46eba3c13d2997ce8593bfdc1682a647058db Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 28 Oct 2024 22:05:10 +0100 Subject: [PATCH 1/2] Exclusively mention CompletableFuture instead of ListenableFuture Closes gh-33805 --- .../aspectj/AnnotationAsyncExecutionAspect.aj | 10 ++++----- .../scheduling/annotation/Async.java | 21 ++++++++++--------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/spring-aspects/src/main/java/org/springframework/scheduling/aspectj/AnnotationAsyncExecutionAspect.aj b/spring-aspects/src/main/java/org/springframework/scheduling/aspectj/AnnotationAsyncExecutionAspect.aj index 46c1b4530ae..14e4c215467 100644 --- a/spring-aspects/src/main/java/org/springframework/scheduling/aspectj/AnnotationAsyncExecutionAspect.aj +++ b/spring-aspects/src/main/java/org/springframework/scheduling/aspectj/AnnotationAsyncExecutionAspect.aj @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,10 +28,10 @@ import org.springframework.scheduling.annotation.Async; *

This aspect routes methods marked with the {@link Async} annotation as well as methods * in classes marked with the same. Any method expected to be routed asynchronously must * return either {@code void}, {@link Future}, or a subtype of {@link Future} (in particular, - * Spring's {@link org.springframework.util.concurrent.ListenableFuture}). This aspect, - * therefore, will produce a compile-time error for methods that violate this constraint - * on the return type. If, however, a class marked with {@code @Async} contains a method - * that violates this constraint, it produces only a warning. + * {@link java.util.concurrent.CompletableFuture}). This aspect, therefore, will produce a + * compile-time error for methods that violate this constraint on the return type. If, + * however, a class marked with {@code @Async} contains a method that violates this + * constraint, it produces only a warning. * *

This aspect needs to be injected with an implementation of a task-oriented * {@link java.util.concurrent.Executor} to activate it for a specific thread pool, diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/Async.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/Async.java index 5d3c290aa3d..6d0ee0b4f20 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/Async.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/Async.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,17 +35,18 @@ import org.springframework.aot.hint.annotation.Reflective; *

In terms of target method signatures, any parameter types are supported. * However, the return type is constrained to either {@code void} or * {@link java.util.concurrent.Future}. In the latter case, you may declare the - * more specific {@link org.springframework.util.concurrent.ListenableFuture} or - * {@link java.util.concurrent.CompletableFuture} types which allow for richer - * interaction with the asynchronous task and for immediate composition with - * further processing steps. + * more specific {@link java.util.concurrent.CompletableFuture} type which allows + * for richer interaction with the asynchronous task and for immediate composition + * with further processing steps. * *

A {@code Future} handle returned from the proxy will be an actual asynchronous - * {@code Future} that can be used to track the result of the asynchronous method - * execution. However, since the target method needs to implement the same signature, - * it will have to return a temporary {@code Future} handle that just passes a value - * through: for example, Spring's {@link AsyncResult}, EJB 3.1's {@link jakarta.ejb.AsyncResult}, - * or {@link java.util.concurrent.CompletableFuture#completedFuture(Object)}. + * {@code (Completable)Future} that can be used to track the result of the + * asynchronous method execution. However, since the target method needs to implement + * the same signature, it will have to return a temporary {@code Future} handle that + * just passes a value after computation in the execution thread: typically through + * {@link java.util.concurrent.CompletableFuture#completedFuture(Object)}. The + * provided value will be exposed to the caller through the actual asynchronous + * {@code Future} handle at runtime. * * @author Juergen Hoeller * @author Chris Beams From 323de1208acf00ebd3bb022055a381907f3c2de4 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 28 Oct 2024 22:08:41 +0100 Subject: [PATCH 2/2] Document limited support for lifecycle management Closes gh-33780 --- .../scheduling/concurrent/SimpleAsyncTaskScheduler.java | 4 +++- .../springframework/core/task/SimpleAsyncTaskExecutor.java | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/spring-context/src/main/java/org/springframework/scheduling/concurrent/SimpleAsyncTaskScheduler.java b/spring-context/src/main/java/org/springframework/scheduling/concurrent/SimpleAsyncTaskScheduler.java index 027d1f6f4f4..d585470e4cf 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/concurrent/SimpleAsyncTaskScheduler.java +++ b/spring-context/src/main/java/org/springframework/scheduling/concurrent/SimpleAsyncTaskScheduler.java @@ -78,7 +78,9 @@ import org.springframework.util.ErrorHandler; * but rather just the hand-off to an execution thread. As a consequence, * a {@link ScheduledFuture} handle (e.g. from {@link #schedule(Runnable, Instant)}) * represents that hand-off rather than the actual completion of the provided task - * (or series of repeated tasks). + * (or series of repeated tasks). Also, this scheduler participates in lifecycle + * management to a limited degree only, stopping trigger firing and fixed-delay + * task execution but not stopping the execution of handed-off tasks. * *

As an alternative to the built-in thread-per-task capability, this scheduler * can also be configured with a separate target executor for scheduled task diff --git a/spring-core/src/main/java/org/springframework/core/task/SimpleAsyncTaskExecutor.java b/spring-core/src/main/java/org/springframework/core/task/SimpleAsyncTaskExecutor.java index 4206695f0b4..8412e6c4aff 100644 --- a/spring-core/src/main/java/org/springframework/core/task/SimpleAsyncTaskExecutor.java +++ b/spring-core/src/main/java/org/springframework/core/task/SimpleAsyncTaskExecutor.java @@ -46,6 +46,11 @@ import org.springframework.util.concurrent.ListenableFutureTask; * executing a large number of short-lived tasks. Alternatively, on JDK 21, * consider setting {@link #setVirtualThreads} to {@code true}. * + *

NOTE: This executor does not participate in context-level lifecycle + * management. Tasks on handed-off execution threads cannot be centrally + * stopped and restarted; if such tight lifecycle management is necessary, + * consider a common {@code ThreadPoolTaskExecutor} setup instead. + * * @author Juergen Hoeller * @since 2.0 * @see #setVirtualThreads