The @async annotation in Spring Boot allows you to run tasks asynchronously (in the background) without blocking the main thread. This is useful for time-consuming tasks like sending emails, processing large files, or making API calls.
Step-by-Step Guide
We will create a Spring Boot app where an API endpoint triggers an async task that runs in the background.
1️⃣ Add Required Dependencies
In your pom.xml, ensure you have the Spring Boot starter dependency:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
Enter fullscreen mode Exit fullscreen mode
Since @async is part of Spring’s task execution framework, no extra dependencies are needed.
2️⃣ Enable Async Processing
In your main application or a configuration class, add @EnableAsync to enable async support.
import org.springframework.context.annotation.Configuration;import org.springframework.scheduling.annotation.EnableAsync;@Configuration@EnableAsync // Enables @Async supportpublic class AsyncConfig {}import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableAsync; @Configuration @EnableAsync // Enables @Async support public class AsyncConfig { }import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableAsync; @Configuration @EnableAsync // Enables @Async support public class AsyncConfig { }
Enter fullscreen mode Exit fullscreen mode
3️⃣ Create an Async Service
This service simulates a long-running task that runs asynchronously.
import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.scheduling.annotation.Async;import org.springframework.stereotype.Service;@Servicepublic class AsyncService {private static final Logger logger = LoggerFactory.getLogger(AsyncService.class);@Async // Runs this method asynchronouslypublic void executeAsyncTask() {logger.info("Task started in thread: {}", Thread.currentThread().getName());try {Thread.sleep(5000); // Simulating a long-running task (5 seconds)} catch (InterruptedException e) {e.printStackTrace();}logger.info("Task completed in thread: {}", Thread.currentThread().getName());}}import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; @Service public class AsyncService { private static final Logger logger = LoggerFactory.getLogger(AsyncService.class); @Async // Runs this method asynchronously public void executeAsyncTask() { logger.info("Task started in thread: {}", Thread.currentThread().getName()); try { Thread.sleep(5000); // Simulating a long-running task (5 seconds) } catch (InterruptedException e) { e.printStackTrace(); } logger.info("Task completed in thread: {}", Thread.currentThread().getName()); } }import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; @Service public class AsyncService { private static final Logger logger = LoggerFactory.getLogger(AsyncService.class); @Async // Runs this method asynchronously public void executeAsyncTask() { logger.info("Task started in thread: {}", Thread.currentThread().getName()); try { Thread.sleep(5000); // Simulating a long-running task (5 seconds) } catch (InterruptedException e) { e.printStackTrace(); } logger.info("Task completed in thread: {}", Thread.currentThread().getName()); } }
Enter fullscreen mode Exit fullscreen mode
Explanation:
The @async annotation tells Spring to run executeAsyncTask() in a separate thread.
Thread.sleep(5000) simulates a 5-second delay, so the task runs in the background.
4️⃣ Create a Controller to Trigger Async Task
We create an API endpoint to trigger the async task.
import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestController@RequestMapping("/api")public class AsyncController {private final AsyncService asyncService;public AsyncController(AsyncService asyncService) {this.asyncService = asyncService;}@GetMapping("/start-task")public String startAsyncTask() {asyncService.executeAsyncTask();return "Async task started! You can continue doing other work.";}}import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/api") public class AsyncController { private final AsyncService asyncService; public AsyncController(AsyncService asyncService) { this.asyncService = asyncService; } @GetMapping("/start-task") public String startAsyncTask() { asyncService.executeAsyncTask(); return "Async task started! You can continue doing other work."; } }import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/api") public class AsyncController { private final AsyncService asyncService; public AsyncController(AsyncService asyncService) { this.asyncService = asyncService; } @GetMapping("/start-task") public String startAsyncTask() { asyncService.executeAsyncTask(); return "Async task started! You can continue doing other work."; } }
Enter fullscreen mode Exit fullscreen mode
Explanation:
Calling /api/start-task will start an async task without blocking the request.
You will immediately receive a response, even though the task is still running in the background.
5️⃣ Run and Test the Application
1️⃣ Start the Spring Boot application
2️⃣ Call the API in a browser or Postman:
http://localhost:8080/api/start-taskhttp://localhost:8080/api/start-taskhttp://localhost:8080/api/start-task
Enter fullscreen mode Exit fullscreen mode
3️⃣ Expected Output in Response:
Async task started! You can continue doing other work.Async task started! You can continue doing other work.Async task started! You can continue doing other work.
Enter fullscreen mode Exit fullscreen mode
4️⃣ Console Output (Logs):
Task started in thread: SimpleAsyncTaskExecutor-1(wait 5 seconds)Task completed in thread: SimpleAsyncTaskExecutor-1Task started in thread: SimpleAsyncTaskExecutor-1 (wait 5 seconds) Task completed in thread: SimpleAsyncTaskExecutor-1Task started in thread: SimpleAsyncTaskExecutor-1 (wait 5 seconds) Task completed in thread: SimpleAsyncTaskExecutor-1
Enter fullscreen mode Exit fullscreen mode
Notice: The logs will print the thread name, confirming the method runs asynchronously in a different thread.
Key Takeaways
@async allows background task execution without blocking the main thread.
Add @EnableAsync to activate async processing.
Methods with @async must return void or CompletableFuture to work correctly.
Useful for sending emails, background processing, API calls, and long-running tasks.
暂无评论内容