Skip to content

Commit

Permalink
Add rule SpringAsyncRules.AsyncMethodsNotCalledFromSameClass
Browse files Browse the repository at this point in the history
  • Loading branch information
rweisleder committed May 29, 2024
1 parent b3a3c45 commit c91bdcc
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/main/docs/userguide.adoc
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
:toc:
:toclevels: 4
:toc-placement!:

= ArchUnit Spring Integration
Expand Down Expand Up @@ -100,6 +101,13 @@ It is most convenient that such methods return `void` or an object implementing

If such methods have other return types, Spring may discard the return value or calling such a method may lead to an exception.

===== Rule AsyncMethodsNotCalledFromSameClass

The rule `SpringAsyncRules.AsyncMethodsNotCalledFromSameClass` ensures that methods annotated with `@Async` or `@Asynchronous` are not called from within the same class.
Such internal calls bypass Spring's proxy mechanism, causing the intended asynchronous behavior to be ignored.

This rule should only be used if caching is used in proxy mode (which is the default mode), see the `@EnableAsync` annotation.

==== SpringCacheRules

===== Rule CacheableMethodsAreProxyable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,18 @@ private SpringAsyncRules() {
.that(are(annotatedWithAsyncOrAsynchronous()))
.should(haveRawReturnType(assignableTo(Void.TYPE).or(assignableTo(Future.class))).as("have return type void or java.util.concurrent.Future"));

/**
* A rule that checks that methods annotated with {@code @Async} or {@code @Asynchronous} are not called from within the same class.
* Such internal calls bypass Spring's proxy mechanism, causing the intended asynchronous behavior to be ignored.
* <p>
* This rule should only be used if caching is used in proxy mode, see the {@code @EnableAsync} annotation.
*
* @see SpringProxyRules#notBeCalledFromWithinTheSameClass()
*/
public static final ArchRule AsyncMethodsNotCalledFromSameClass = methods()
.that(are(annotatedWithAsyncOrAsynchronous()))
.should(notBeCalledFromWithinTheSameClass());

private static DescribedPredicate<JavaMethod> annotatedWithAsyncOrAsynchronous() {
DescribedPredicate<JavaMethod> async = springAnnotatedWith("org.springframework.scheduling.annotation.Async").forSubtype();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,14 @@ void provides_a_description() {
assertThat(description).isEqualTo("methods that are annotated with @Async or @Asynchronous should have return type void or java.util.concurrent.Future");
}
}

@Nested
class Rule_AsyncMethodsNotCalledFromSameClass {

@Test
void provides_a_description() {
String description = SpringAsyncRules.AsyncMethodsNotCalledFromSameClass.getDescription();
assertThat(description).isEqualTo("methods that are annotated with @Async or @Asynchronous should not be called from within the same class");
}
}
}

0 comments on commit c91bdcc

Please sign in to comment.