@Async异步注解

文章目录

  • 使用说明
  • 无返回值
  • 有返回值
  • 多任务有返回值
  • 同类中调用

使用说明

在 Spring 框架中,@Async 注解用于标识一个方法是异步执行的。当一个方法被 @Async 注解修饰后,调用该方法时会在新的线程中执行,而不会阻塞当前线程。
要使用 @Async 注解,需要满足以下条件:

  1. Spring Boot 应用中,需要在启动类或配置类上添加 @EnableAsync 注解来启用异步方法的支持。
  2. 在需要异步执行的方法上添加 @Async 注解。

无返回值

定义异步任务


	@Async
	@Override
	public void testAsync1() {
		// 业务逻辑
	}
	

调用异步任务


	@GetMapping("/test")
	public Object test() {
		asyncService.testAsync1();	
		return "testAsync1";
	}
	

有返回值

定义异步任务


	@Async
	@Override
	public Future<String> testAsync2() {
		String str = "testAsync2"; 
		return new AsyncResult<>(str);
	}
	

调用异步任务


	@GetMapping("/test")
	public Object test() {
		Future<String> f = asyncService.testAsync2();	
		return f.get();
	}
	

多任务有返回值

可以延用Future或使用CompletableFuture
定义异步任务


	@Async
	@Override
	public CompletableFuture<String> testAsync1() {
		String str = "testAsync1";
		return CompletableFuture.completedFuture(str);
	}
	
	@Async
	@Override
	public CompletableFuture<String> testAsync2() {
		String str = "testAsync2";
		return CompletableFuture.completedFuture(str);
	}
	
	@Async
	@Override
	public CompletableFuture<String> testAsync3() {
		String str = "testAsync3";
		return CompletableFuture.completedFuture(str);
	}
	

调用异步任务


	@GetMapping("/test")
	public Object test() {
	
		CompletableFuture<Integer> f1 = asyncService.testAsync1();
		CompletableFuture<Integer> f2 = asyncService.testAsync2();
		CompletableFuture<Integer> f3 = asyncService.testAsync3();

		Map<String, Integer> map = CompletableFuture.allOf(f1, f2, f3).thenApply(v ->
				new HashMap<String, Integer>() {{
					try {
						put("task_1", f1.get());
						put("task_2", f2.get());
						put("task_3", f3.get());
					} catch (InterruptedException | ExecutionException e) {
						throw new RuntimeException(e);
					}
				}}).join();
				
		return map;
	}

	

同类中调用

同一个类中使用@Async调用异步方法会失效,这是因为 Spring 在同一个类中调用异步方法时,实际上是通过代理对象来调用方法的,而代理对象会绕过原始对象的自我调用,导致异步方法的注解失效。
解决方法是在同一个类中手动获取当前类的代理对象来调用@Async异步方法,而不是直接调用该方法。


	@Autowired
	private ApplicationContext context;
	
	@GetMapping("/test")
	public Object test() throws Exception {
	
	    // 通过 ApplicationContext 获取 MyClass 类的一个代理对象
	    MyClass proxy = context.getBean(MyClass.class);
	
	    // 调用异步方法
	    proxy.testAsync();
	
	    // 返回字符串 "testAsync" 给客户端
	    return "testAsync";
	}
	
	@Async
	public void testAsync() {
	    // 异步方法,可以在这里编写业务逻辑
	}

	

你可能感兴趣的:(java,spring,boot,异步)