rspec/rules/S6809/java/rule.adoc

72 lines
2.3 KiB
Plaintext

== Why is this an issue?
A method annotated with Spring's `@Async` or `@Transactional` annotations will not work as expected
if invoked directly from within its class.
This is because Spring generates a proxy class with wrapper code to manage the method's asynchronicity (`@Async`)
or to handle the transaction (`@Transactional`).
However, when called using `this`, the proxy instance is bypassed, and the method is invoked directly
without the required wrapper code.
== How to fix it
Replace calls to `@Async` or `@Transactional` methods via `this`
with calls on an instance that was injected by Spring (`@Autowired`, `@Resource` or `@Inject`).
The injected instance is a proxy on which the methods can be invoked safely.
=== Code examples
==== Noncompliant code example
[source,java,diff-id=1,diff-type=noncompliant]
----
@Service
public class AsyncNotificationProcessor implements NotificationProcessor {
@Override
public void process(Notification notification) {
processAsync(notification); // Noncompliant, call bypasses proxy
}
@Async
public processAsync(Notification notification) {
// ...
}
}
----
==== Compliant solution
[source,java,diff-id=1,diff-type=compliant]
----
@Service
public class AsyncNotificationProcessor implements NotificationProcessor {
@Resource
private AsyncNotificationProcessor
@Override
public void process(Notification notification) {
asyncNotificationProcessor.processAsync(notification); // Compliant, call via injected proxy
}
@Async
public processAsync(Notification notification) {
// ...
}
}
----
== Resources
=== Documentation
- https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/scheduling/annotation/Async.html[Spring Framework API - Annotation Interface Async]
- https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/annotation/Transactional.html[Spring Framework API - Annotation Interface Transactional]
=== Articles & blog posts
- https://www.baeldung.com/spring-async[Baeldung - How To Do @Async in Spring]
- https://stackoverflow.com/questions/22561775/spring-async-ignored[Stack Overflow - Spring @Async ignored]
- https://stackoverflow.com/questions/4396284/does-spring-transactional-attribute-work-on-a-private-method[Stack Overflow - Does Spring @Transactional attribute work on a private method?]