详解springboot中使用异步的常用两种方式及其比较
一般对于业务复杂的流程,会有一些处理逻辑不需要及时返回,甚至不需要返回值,但是如果充斥在主流程中,占用大量时间来处理,就可以通过异步的方式来优化。
实现异步的常用方法远不止两种,但是个人经验常用的,好用的,这里我就说两种,最好用的是第二种。
- spring的注解方式@Asyncorg.springframework.scheduling.annotation.Async
- jdk1.8后的CompletableFuturejava.util.concurrent.CompletableFuture
其中第一种的使用注意事项比较多
1.不要在本类中异步调用。即一个方法是异步方法,然后用另一个方法调用这个异步方法。
2.不要有返回值,使用void
3.不能使用本类的私有方法或者非接口化加注@Async,因为代理不到失效
4.异步方法不能使用static修饰
5.异步类需使用@Component注解,不然将导致spring无法扫描到异步类
6.SpringBoot框架必须在启动类中增加@EnableAsync注解
7.异步方法不要和事物注解同时存在。可以在事物的方法中调用另外一个类中的异步方法。在调用Async方法的方法上标注@Transactional是管理调用方法的事务的,在Async方法上标注@Transactional是管理异步方法的事务,事务因线程隔离
@Async的使用方式
1.pom引入依赖。只要依赖中存在spring-context包即可。
2.需要在springboot启动类上加上开启异步的注解@EnableAsync
importorg.springframework.boot.SpringApplication; importorg.springframework.boot.autoconfigure.SpringBootApplication; importorg.springframework.boot.builder.SpringApplicationBuilder; importorg.springframework.boot.web.servlet.support.SpringBootServletInitializer; importorg.springframework.cloud.netflix.hystrix.EnableHystrix; importorg.springframework.cloud.openfeign.EnableFeignClients; importorg.springframework.scheduling.annotation.EnableAsync; @EnableAsync @EnableHystrix @EnableFeignClients @SpringBootApplication publicclassOrderServerApplicationextendsSpringBootServletInitializer{ @Override protectedSpringApplicationBuilderconfigure(SpringApplicationBuilderapplication){ returnapplication.sources(OrderServerApplication.class); } publicstaticvoidmain(String[]args){ SpringApplication.run(OrderServerApplication.class,args); } }
3.可以专门封装一个异步类。然后那个方法需要用到异步的操作。在这个类中封装,然后在类中引入异步类即可。
在使用异步的地方引入调用即可。
CompletableFuture中的异步方法是在一个正常的方法体内使用即可。
privateExecutorServicepool=Executors.newFixedThreadPool(2); @Override publicvoidsynOrder(StringorderId,OrderSourceEnumtype,Integerstatus){ try{ CompletableFuture.runAsync(()->{ //下面是一些业务操作。 PageVOpageVO=newPageVO(); SetorderIds=newHashSet<>(); orderIds.add(orderId); pageVO.setIds(orderIds); pageVO.setOrderType(type); List maisOrderDTOS=orderSourceService.batchGetDetails(pageVO); if(CollectionUtils.isEmpty(maisOrderDTOS)){ thrownewRuntimeException("未找到id="+orderId+"类型为:"+type.getDesc()+"的订单"); } },pool); }catch(Exceptione){ log.info("同步单个订单给群脉出现异常:{}",e); } }
参考博客:[Java并发-15]CompletableFuture:异步编程
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。