Skip to main content

Avoid Using @Async Annotation in @Configuration Classes in Spring Boot

High
maintainabilityreliabilityarchitecture

What is it?

This practice highlights the misuse of the @Async annotation within methods of a class annotated with @Configuration in Spring Boot.

Why apply it?

Using @Async in @Configuration classes is problematic because it can lead to unexpected behavior due to the asynchronous infrastructure not being properly set up or inappropriate for a configuration context. The @Async annotation is designed for asynchronous method execution outside of a configuration class.

How to fix it?

Remove the @Async annotation from methods within @Configuration classes. Instead, delegate asynchronous processing to appropriate service-like components.

Examples

Example 1:

Negative

In this noncompliant example, a method within the @Configuration class is annotated with @Async, which is incorrect.

@EnableAsync
@Configuration
public class InvalidConfiguration {

@Async // Noncompliant
public void performAsyncTask() {
// Asynchronous logic here
}

@Bean
public MyComponent myComponent() {
return new MyComponent();
}
}

Example 2:

Positive

In this compliant example, no method within the @Configuration class uses the @Async annotation. Asynchronous processing, if needed, should be handled elsewhere.

@EnableAsync
@Configuration
public class MyConfiguration {

@Bean
public MyService myService() {
return new MyService();
}

public void setup() {
// Setup logic here
}
}

Negative

This example incorrectly places an @Async annotation on a method within a @Configuration class, which should be avoided.

@EnableAsync
@Configuration
public class WrongConfig {

@Async // Noncompliant
public void asyncOperation() {
// Logic meant to be asynchronous
}

@Bean
public SomeOtherBean someOtherBean() {
return new SomeOtherBean();
}
}

Example 3:

Positive

This example demonstrates how to properly separate asynchronous logic into a service class rather than placing it within a @Configuration class.

@EnableAsync
@Configuration
public class AppConfig {

@Bean
public TaskExecutor taskExecutor() {
return new ThreadPoolTaskExecutor();
}

@Bean
public AsyncService asyncService() {
return new AsyncService();
}
}