|
1 | 1 | /*
|
2 |
| - * Copyright 2002-2013 the original author or authors. |
| 2 | + * Copyright 2002-2014 the original author or authors. |
3 | 3 | *
|
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
5 | 5 | * you may not use this file except in compliance with the License.
|
|
13 | 13 | * See the License for the specific language governing permissions and
|
14 | 14 | * limitations under the License.
|
15 | 15 | */
|
| 16 | + |
16 | 17 | package org.springframework.web.context.request.async;
|
17 | 18 |
|
18 | 19 | import java.util.concurrent.Callable;
|
19 | 20 |
|
20 | 21 | import org.springframework.beans.factory.BeanFactory;
|
| 22 | +import org.springframework.beans.factory.BeanFactoryAware; |
21 | 23 | import org.springframework.core.task.AsyncTaskExecutor;
|
22 | 24 | import org.springframework.util.Assert;
|
23 | 25 | import org.springframework.web.context.request.NativeWebRequest;
|
|
26 | 28 | * Holder for a {@link Callable}, a timeout value, and a task executor.
|
27 | 29 | *
|
28 | 30 | * @author Rossen Stoyanchev
|
| 31 | + * @author Juergen Hoeller |
29 | 32 | * @since 3.2
|
30 | 33 | */
|
31 |
| -public class WebAsyncTask<V> { |
| 34 | +public class WebAsyncTask<V> implements BeanFactoryAware { |
32 | 35 |
|
33 | 36 | private final Callable<V> callable;
|
34 | 37 |
|
35 |
| - private final Long timeout; |
| 38 | + private Long timeout; |
| 39 | + |
| 40 | + private AsyncTaskExecutor executor; |
36 | 41 |
|
37 |
| - private final String executorName; |
| 42 | + private String executorName; |
38 | 43 |
|
39 |
| - private final AsyncTaskExecutor executor; |
| 44 | + private BeanFactory beanFactory; |
40 | 45 |
|
41 | 46 | private Callable<V> timeoutCallback;
|
42 | 47 |
|
43 | 48 | private Runnable completionCallback;
|
44 | 49 |
|
45 |
| - private BeanFactory beanFactory; |
46 |
| - |
47 | 50 |
|
48 | 51 | /**
|
49 | 52 | * Create a {@code WebAsyncTask} wrapping the given {@link Callable}.
|
50 | 53 | * @param callable the callable for concurrent handling
|
51 | 54 | */
|
52 | 55 | public WebAsyncTask(Callable<V> callable) {
|
53 |
| - this(null, null, null, callable); |
| 56 | + Assert.notNull(callable, "Callable must not be null"); |
| 57 | + this.callable = callable; |
54 | 58 | }
|
55 | 59 |
|
56 | 60 | /**
|
57 | 61 | * Create a {@code WebAsyncTask} with a timeout value and a {@link Callable}.
|
58 |
| - * @param timeout timeout value in milliseconds |
| 62 | + * @param timeout a timeout value in milliseconds |
59 | 63 | * @param callable the callable for concurrent handling
|
60 | 64 | */
|
61 | 65 | public WebAsyncTask(long timeout, Callable<V> callable) {
|
62 |
| - this(timeout, null, null, callable); |
| 66 | + this(callable); |
| 67 | + this.timeout = timeout; |
63 | 68 | }
|
64 | 69 |
|
65 | 70 | /**
|
66 | 71 | * Create a {@code WebAsyncTask} with a timeout value, an executor name, and a {@link Callable}.
|
67 | 72 | * @param timeout timeout value in milliseconds; ignored if {@code null}
|
| 73 | + * @param executorName the name of an executor bean to use |
68 | 74 | * @param callable the callable for concurrent handling
|
69 | 75 | */
|
70 | 76 | public WebAsyncTask(Long timeout, String executorName, Callable<V> callable) {
|
71 |
| - this(timeout, null, executorName, callable); |
72 |
| - Assert.notNull(executor, "Executor name must not be null"); |
| 77 | + this(callable); |
| 78 | + Assert.notNull(executorName, "Executor name must not be null"); |
| 79 | + this.executorName = executorName; |
| 80 | + this.timeout = timeout; |
73 | 81 | }
|
74 | 82 |
|
75 | 83 | /**
|
76 | 84 | * Create a {@code WebAsyncTask} with a timeout value, an executor instance, and a Callable.
|
77 | 85 | * @param timeout timeout value in milliseconds; ignored if {@code null}
|
| 86 | + * @param executor the executor to use |
78 | 87 | * @param callable the callable for concurrent handling
|
79 | 88 | */
|
80 | 89 | public WebAsyncTask(Long timeout, AsyncTaskExecutor executor, Callable<V> callable) {
|
81 |
| - this(timeout, executor, null, callable); |
| 90 | + this(callable); |
82 | 91 | Assert.notNull(executor, "Executor must not be null");
|
83 |
| - } |
84 |
| - |
85 |
| - private WebAsyncTask(Long timeout, AsyncTaskExecutor executor, String executorName, Callable<V> callable) { |
86 |
| - Assert.notNull(callable, "Callable must not be null"); |
87 |
| - this.callable = callable; |
88 |
| - this.timeout = timeout; |
89 | 92 | this.executor = executor;
|
90 |
| - this.executorName = executorName; |
| 93 | + this.timeout = timeout; |
91 | 94 | }
|
92 | 95 |
|
93 | 96 |
|
94 | 97 | /**
|
95 |
| - * Return the {@link Callable} to use for concurrent handling, never {@code null}. |
| 98 | + * Return the {@link Callable} to use for concurrent handling (never {@code null}). |
96 | 99 | */
|
97 | 100 | public Callable<?> getCallable() {
|
98 | 101 | return this.callable;
|
99 | 102 | }
|
100 | 103 |
|
101 | 104 | /**
|
102 |
| - * Return the timeout value in milliseconds or {@code null} if not value is set. |
| 105 | + * Return the timeout value in milliseconds, or {@code null} if no timeout is set. |
103 | 106 | */
|
104 | 107 | public Long getTimeout() {
|
105 | 108 | return this.timeout;
|
106 | 109 | }
|
107 | 110 |
|
108 | 111 | /**
|
109 |
| - * Return the AsyncTaskExecutor to use for concurrent handling, or {@code null}. |
| 112 | + * A {@link BeanFactory} to use for resolving an executor name. |
| 113 | + * <p>This factory reference will automatically be set when |
| 114 | + * {@code WebAsyncTask} is used within a Spring MVC controller. |
| 115 | + */ |
| 116 | + public void setBeanFactory(BeanFactory beanFactory) { |
| 117 | + this.beanFactory = beanFactory; |
| 118 | + } |
| 119 | + |
| 120 | + /** |
| 121 | + * Return the AsyncTaskExecutor to use for concurrent handling, |
| 122 | + * or {@code null} if none specified. |
110 | 123 | */
|
111 | 124 | public AsyncTaskExecutor getExecutor() {
|
112 | 125 | if (this.executor != null) {
|
113 | 126 | return this.executor;
|
114 | 127 | }
|
115 | 128 | else if (this.executorName != null) {
|
116 |
| - Assert.state(this.beanFactory != null, "A BeanFactory is required to look up a task executor bean"); |
| 129 | + Assert.state(this.beanFactory != null, "BeanFactory is required to look up an executor bean by name"); |
117 | 130 | return this.beanFactory.getBean(this.executorName, AsyncTaskExecutor.class);
|
118 | 131 | }
|
119 | 132 | else {
|
120 | 133 | return null;
|
121 | 134 | }
|
122 | 135 | }
|
123 | 136 |
|
124 |
| - /** |
125 |
| - * A {@link BeanFactory} to use to resolve an executor name. Applications are |
126 |
| - * not expected to have to set this property when {@code WebAsyncTask} is used in a |
127 |
| - * Spring MVC controller. |
128 |
| - */ |
129 |
| - public void setBeanFactory(BeanFactory beanFactory) { |
130 |
| - this.beanFactory = beanFactory; |
131 |
| - } |
132 |
| - |
133 | 137 |
|
134 | 138 | /**
|
135 |
| - * Register code to invoke when the async request times out. This method is |
136 |
| - * called from a container thread when an async request times out before the |
137 |
| - * {@code Callable} has completed. The callback is executed in the same |
138 |
| - * thread and therefore should return without blocking. It may return an |
139 |
| - * alternative value to use, including an {@link Exception} or return |
| 139 | + * Register code to invoke when the async request times out. |
| 140 | + * <p>This method is called from a container thread when an async request times |
| 141 | + * out before the {@code Callable} has completed. The callback is executed in |
| 142 | + * the same thread and therefore should return without blocking. It may return |
| 143 | + * an alternative value to use, including an {@link Exception} or return |
140 | 144 | * {@link CallableProcessingInterceptor#RESULT_NONE RESULT_NONE}.
|
141 | 145 | */
|
142 | 146 | public void onTimeout(Callable<V> callback) {
|
143 | 147 | this.timeoutCallback = callback;
|
144 | 148 | }
|
145 | 149 |
|
146 | 150 | /**
|
147 |
| - * Register code to invoke when the async request completes. This method is |
148 |
| - * called from a container thread when an async request completed for any |
149 |
| - * reason including timeout and network error. |
| 151 | + * Register code to invoke when the async request completes. |
| 152 | + * <p>This method is called from a container thread when an async request |
| 153 | + * completed for any reason, including timeout and network error. |
150 | 154 | */
|
151 | 155 | public void onCompletion(Runnable callback) {
|
152 | 156 | this.completionCallback = callback;
|
153 | 157 | }
|
154 | 158 |
|
155 | 159 | CallableProcessingInterceptor getInterceptor() {
|
156 | 160 | return new CallableProcessingInterceptorAdapter() {
|
157 |
| - |
158 | 161 | @Override
|
159 | 162 | public <T> Object handleTimeout(NativeWebRequest request, Callable<T> task) throws Exception {
|
160 |
| - return (timeoutCallback != null) ? timeoutCallback.call() : CallableProcessingInterceptor.RESULT_NONE; |
| 163 | + return (timeoutCallback != null ? timeoutCallback.call() : CallableProcessingInterceptor.RESULT_NONE); |
161 | 164 | }
|
162 |
| - |
163 | 165 | @Override
|
164 | 166 | public <T> void afterCompletion(NativeWebRequest request, Callable<T> task) throws Exception {
|
165 | 167 | if (completionCallback != null) {
|
|
0 commit comments