|
|
|
@ -1,5 +1,5 @@ |
|
|
|
/* |
|
|
|
/* |
|
|
|
* Copyright 2002-2012 the original author or authors. |
|
|
|
* Copyright 2002-2015 the original author or authors. |
|
|
|
* |
|
|
|
* |
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
|
|
* you may not use this file except in compliance with the License. |
|
|
|
* you may not use this file except in compliance with the License. |
|
|
|
@ -23,15 +23,15 @@ import org.springframework.core.annotation.AnnotationUtils; |
|
|
|
import org.springframework.scheduling.annotation.Async; |
|
|
|
import org.springframework.scheduling.annotation.Async; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Aspect to route methods based on the {@link Async} annotation. |
|
|
|
* Aspect to route methods based on Spring's {@link Async} annotation. |
|
|
|
* |
|
|
|
* |
|
|
|
* <p>This aspect routes methods marked with the {@link Async} annotation |
|
|
|
* <p>This aspect routes methods marked with the {@link Async} annotation as well as methods |
|
|
|
* as well as methods in classes marked with the same. Any method expected |
|
|
|
* in classes marked with the same. Any method expected to be routed asynchronously must |
|
|
|
* to be routed asynchronously must return either {@code void}, {@link Future}, |
|
|
|
* return either {@code void}, {@link Future}, or a subtype of {@link Future} (in particular, |
|
|
|
* or a subtype of {@link Future}. This aspect, therefore, will produce |
|
|
|
* Spring's {@link org.springframework.util.concurrent.ListenableFuture}). This aspect, |
|
|
|
* a compile-time error for methods that violate this constraint on the return type. |
|
|
|
* therefore, will produce a compile-time error for methods that violate this constraint |
|
|
|
* If, however, a class marked with {@code @Async} contains a method that violates this |
|
|
|
* on the return type. If, however, a class marked with {@code @Async} contains a method |
|
|
|
* constraint, it produces only a warning. |
|
|
|
* that violates this constraint, it produces only a warning. |
|
|
|
* |
|
|
|
* |
|
|
|
* @author Ramnivas Laddad |
|
|
|
* @author Ramnivas Laddad |
|
|
|
* @author Chris Beams |
|
|
|
* @author Chris Beams |
|
|
|
@ -39,42 +39,41 @@ import org.springframework.scheduling.annotation.Async; |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public aspect AnnotationAsyncExecutionAspect extends AbstractAsyncExecutionAspect { |
|
|
|
public aspect AnnotationAsyncExecutionAspect extends AbstractAsyncExecutionAspect { |
|
|
|
|
|
|
|
|
|
|
|
private pointcut asyncMarkedMethod() |
|
|
|
private pointcut asyncMarkedMethod() : execution(@Async (void || Future+) *(..)); |
|
|
|
: execution(@Async (void || Future+) *(..)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private pointcut asyncTypeMarkedMethod() |
|
|
|
private pointcut asyncTypeMarkedMethod() : execution((void || Future+) (@Async *).*(..)); |
|
|
|
: execution((void || Future+) (@Async *).*(..)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public pointcut asyncMethod() : asyncMarkedMethod() || asyncTypeMarkedMethod(); |
|
|
|
public pointcut asyncMethod() : asyncMarkedMethod() || asyncTypeMarkedMethod(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* {@inheritDoc} |
|
|
|
* This implementation inspects the given method and its declaring class for the |
|
|
|
* <p>This implementation inspects the given method and its declaring class for the |
|
|
|
* {@code @Async} annotation, returning the qualifier value expressed by {@link Async#value()}. |
|
|
|
* {@code @Async} annotation, returning the qualifier value expressed by |
|
|
|
* If {@code @Async} is specified at both the method and class level, the method's |
|
|
|
* {@link Async#value()}. If {@code @Async} is specified at both the method and class level, the |
|
|
|
* {@code #value} takes precedence (even if empty string, indicating that the default |
|
|
|
* method's {@code #value} takes precedence (even if empty string, indicating that |
|
|
|
* executor should be used preferentially). |
|
|
|
* the default executor should be used preferentially). |
|
|
|
|
|
|
|
* @return the qualifier if specified, otherwise empty string indicating that the |
|
|
|
* @return the qualifier if specified, otherwise empty string indicating that the |
|
|
|
* {@linkplain #setExecutor(Executor) default executor} should be used |
|
|
|
* {@linkplain #setExecutor default executor} should be used |
|
|
|
* @see #determineAsyncExecutor(Method) |
|
|
|
* @see #determineAsyncExecutor(Method) |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
@Override |
|
|
|
@Override |
|
|
|
protected String getExecutorQualifier(Method method) { |
|
|
|
protected String getExecutorQualifier(Method method) { |
|
|
|
// maintainer's note: changes made here should also be made in |
|
|
|
// Maintainer's note: changes made here should also be made in |
|
|
|
// AnnotationAsyncExecutionInterceptor#getExecutorQualifier |
|
|
|
// AnnotationAsyncExecutionInterceptor#getExecutorQualifier |
|
|
|
Async async = AnnotationUtils.findAnnotation(method, Async.class); |
|
|
|
Async async = AnnotationUtils.findAnnotation(method, Async.class); |
|
|
|
if (async == null) { |
|
|
|
if (async == null) { |
|
|
|
async = AnnotationUtils.findAnnotation(method.getDeclaringClass(), Async.class); |
|
|
|
async = AnnotationUtils.findAnnotation(method.getDeclaringClass(), Async.class); |
|
|
|
} |
|
|
|
} |
|
|
|
return async == null ? null : async.value(); |
|
|
|
return (async != null ? async.value() : null); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
declare error: |
|
|
|
declare error: |
|
|
|
execution(@Async !(void||Future) *(..)): |
|
|
|
execution(@Async !(void || Future+) *(..)): |
|
|
|
"Only methods that return void or Future may have an @Async annotation"; |
|
|
|
"Only methods that return void or Future may have an @Async annotation"; |
|
|
|
|
|
|
|
|
|
|
|
declare warning: |
|
|
|
declare warning: |
|
|
|
execution(!(void||Future) (@Async *).*(..)): |
|
|
|
execution(!(void || Future+) (@Async *).*(..)): |
|
|
|
"Methods in a class marked with @Async that do not return void or Future will " + |
|
|
|
"Methods in a class marked with @Async that do not return void or Future will " + |
|
|
|
"be routed synchronously"; |
|
|
|
"be routed synchronously"; |
|
|
|
|
|
|
|
|
|
|
|
|