package com.example.demo.controller;
import com.example.demo.service.AsyncService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
@RestController
@RequestMapping("/async")
public class AsyncController {
@Resource
private AsyncService asyncService;
/**
* 测试eureka
*/
@Resource
RestTemplate restTemplate;
@RequestMapping("/test1")
public void fun01(){
// 服务id
String serverId = "TEST";
// 通过服务id 调用
ResponseEntity<Map> responseEntity = restTemplate.getForEntity("http://" + serverId + "/async/test", Map.class);
Map body = responseEntity.getBody();
System.out.println(body);
}
@RequestMapping("/test")
public void test(){
//异步调用无返回值
asyncService.test();
System.out.println("主线程");
}
@RequestMapping("/testReturn")
public void testReturn() throws ExecutionException, InterruptedException {
//异步调用有返回值
Future<String> future = asyncService.testReturn();
System.out.println(future.get());
System.out.println("主线程");
}
}
package com.example.demo.service.Impl;
import com.example.demo.service.AsyncService;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import java.util.concurrent.Future;
@Service
public class AsyncServiceImpl implements AsyncService {
@Async
@Override
public void test() {
async();
}
/**
* 有返回值的情况下,虽然异步业务逻辑是由新线程执行,但如果在主线程操作返回值对象,主线程会等待,还是顺序执行
* @return Future<String>
*/
@Async
@Override
public Future<String> testReturn() {
async();
return AsyncResult.forValue("测试异步调用有返回接口");
}
private void async(){
System.out.println("进入异步调用");
long startTime = System.currentTimeMillis();
try {
Thread.sleep(3000);
}catch (Exception e){
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println(endTime - startTime);
}
}
启动类上添加:
@EnableAsync //开启异步调用
注意:spring 在扫描bean的时候会扫描方法上是否包含@Async注解,如果包含,spring会为这个bean动态地生成一个子类(即代理类,proxy),代理类是继承原来那个bean的。此时,当这个有注解的方法被调用的时候,实际上是由代理类来调用的,代理类在调用时增加异步作用。然而,如果这个有注解的方法是被同一个类中的其他方法调用的,那么该方法的调用并没有通过代理类,而是直接通过原来的那个bean,所以就没有增加异步作用,我们看到的现象就是@Async注解无效。