java asynservice_spring使用@Async注解异步处理

本文介绍了Java中Spring框架的@Async注解用于实现异步调用的原理和使用方法。详细讨论了异步调用的概念,常规异步处理方式,@Async的使用场景,包括无参数、带参数及返回Future的异步调用。同时,文章还探讨了@Async与@Transactional事务管理的配合以及@EnableAsync的启用。通过一个实例展示了如何在Controller、Service层使用@Async进行数据库操作,以实现异步插入数据。
摘要由CSDN通过智能技术生成

1. 何为异步调用?

在解释异步调用之前,我们先来看同步调用的定义;同步就是整个处理过程顺序执行,当各个过程都执行完毕,并返回结果。 异步调用则是只是发送了调用的指令,调用者无需等待被调用的方法完全执行完毕;而是继续执行下面的流程。例如, 在某个调用中,需要顺序调用 A, B, C三个过程方法;如他们都是同步调用,则需要将他们都顺序执行完毕之后,方算作过程执行完毕; 如B为一个异步的调用方法,则在执行完A之后,调用B,并不等待B完成,而是执行开始调用C,待C执行完毕之后,就意味着这个过程执行完毕了。

2. 常规的异步调用处理方式

在Java中,一般在处理类似的场景之时,都是基于创建独立的线程去完成相应的异步调用逻辑,通过主线程和不同的线程之间的执行流程,从而在启动独立的线程之后,主线程继续执行而不会产生停滞等待的情况。

3. @Async介绍

在Spring中,基于@Async标注的方法,称之为异步方法;这些方法将在执行的时候,将会在独立的线程中被执行,调用者无需等待它的完成,即可继续其他的操作。

分为不带参数的异步调用;带参数的异步调用;调用返回Future的异步线程

4. @Async调用中的事务处理机制

在@Async标注的方法,同时也适用了@Transactional进行了标注;在其调用数据库操作之时,将无法产生事务管理的控制,原因就在于其是基于异步处理的操作。 那该如何给这些操作添加事务管理呢?可以将需要事务管理操作的方法放置到异步方法内部,在内部被调用的方法上添加@Transactional. 例如: 方法A,使用了@Async/@Transactional来标注,但是无法产生事务控制的目的。 方法B,使用了@Async来标注, B中调用了C、D,C/D分别使用@Transactional做了标注,则可实现事务控制的目的。

5. 配合使用@EnableAsync

@EnableAsync

在启动类或者Control类加上 @EnableAsync 注解

@EnableAsync注解的意思是可以异步执行,就是开启多线程的意思。可以标注在方法、类上。@Async所修饰的函数不要定义为static类型,这样异步调用不会生效

如下:

@SpringBootApplication

@EnableAsync

public class Application

{

public static void main( String[] args )

{

SpringApplication.run(Application.class, args);

}

}

或者:

@EnableAsync

@RestController

public class HelloController {

@Autowired

TestAsyncService testAsyncService;

}

6. 举例:

两张表:user_info和order_table 插入user_info数据时候用同步,插入order_table用异步。

在controller类中创建一个方法 同时保存user_info和order_table表。保存order_table用异步(对应service方法中用@Async标注)

(1)domain文件夹中创建Entity类

packagecom.cfj.ceshi.async.domain;importjava.io.Serializable;importjava.util.Date;importjavax.persistence.Column;importjavax.persistence.Entity;importjavax.persistence.GeneratedValue;importjavax.persistence.GenerationType;importjavax.persistence.Id;importjavax.persistence.Table;

@Entity

@Table(name="order_table")public class OrderTable implementsSerializable {private static final long serialVersionUID = 1L;

@Id

@GeneratedValue(strategy=GenerationType.AUTO)privateInteger id;

@Column(name= "order_name")privateString orderName;

@Column(name= "user_id")privateInteger userId;

@Column(name= "create_date")privateDate createDate;publicInteger getId() {returnid;

}public voidsetId(Integer id) {this.id =id;

}publicString getOrderName() {returnorderName;

}public voidsetOrderName(String orderName) {this.orderName =orderName;

}publicInteger getUserId() {returnuserId;

}public voidsetUserId(Integer userId) {this.userId =userId;

}publicDate getCreateDate() {returncreateDate;

}public voidsetCreateDate(Date createDate) {this.createDate =createDate;

}

}

packagecom.cfj.ceshi.async.domain;importjava.io.Serializable;importjavax.persistence.Entity;importjavax.persistence.GeneratedValue;importjavax.persistence.GenerationType;importjavax.persistence.Id;importjavax.persistence.Table;

@Entity

@Table(name="user_info")public class UserInfo implementsSerializable {private static final long serialVersionUID = 1L;

@Id

@GeneratedValue(strategy=GenerationType.AUTO)privateInteger id;privateString userName;privateString age;publicInteger getId() {returnid;

}public voidsetId(Integer id) {this.id =id;

}publicString getUserName() {returnuserName;

}public voidsetUserName(String userName) {this.userName =userName;

}publicString getAge() {returnage;

}public voidsetAge(String age) {this.age =age;

}

@OverridepublicString toString() {return "UserInfo [id=" + id + ", userName=" + userName + ", age=" + age + "]";

}

}

(2)创建repository层操作数据库。如果是普通保存方法,只需要接口继承JpaRepository,不需要写具体方法

packagecom.cfj.ceshi.async.repository;importorg.springframework.data.jpa.repository.JpaRepository;importcom.cfj.ceshi.async.domain.OrderTable;public interface OrderRepository extends JpaRepository{

}

packagecom.cfj.ceshi.async.repository;importorg.springframework.data.jpa.repository.JpaRepository;importcom.cfj.ceshi.async.domain.UserInfo;public interface UserRepository extends JpaRepository{

}

(3)service层 其中order的实现层保存方法加上@Async

packagecom.cfj.ceshi.async.service;public interfaceOrderService {public voidsaveOrder(Integer UserId,String name);

}

packagecom.cfj.ceshi.async.service;importjava.util.List;importcom.cfj.ceshi.async.domain.UserInfo;public interfaceUserService {publicInteger save(UserInfo user);

}

packagecom.cfj.ceshi.async.service.impl;importjava.util.Date;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.scheduling.annotation.Async;importorg.springframework.stereotype.Service;importcom.cfj.ceshi.async.domain.OrderTable;importcom.cfj.ceshi.async.repository.OrderRepository;importcom.cfj.ceshi.async.service.OrderService;

@Servicepublic class OrderServiceImpl implementsOrderService {

@Autowired

OrderRepository orderRepository;/*** 异步保存*/@Async

@Overridepublic voidsaveOrder(Integer UserId,String name) {

System.out.println("UserId:"+UserId);

System.out.println("=====" + Thread.currentThread().getName() + "=========");

OrderTable orderTable= newOrderTable();

orderTable.setOrderName(name+"订单");

orderTable.setUserId(UserId);

orderTable.setCreateDate(newDate());

orderRepository.save(orderTable);

}

}

packagecom.cfj.ceshi.async.service.impl;importjava.util.List;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;importorg.springframework.transaction.annotation.Transactional;importcom.cfj.ceshi.async.domain.UserInfo;importcom.cfj.ceshi.async.repository.UserRepository;importcom.cfj.ceshi.async.service.UserService;

@Service

@Transactionalpublic class UserServiceImpl implementsUserService{

@AutowiredprivateUserRepository userRepository;

@OverridepublicInteger save(UserInfo user) {

System.out.println("=====" + Thread.currentThread().getName() + "=========");returnuserRepository.save(user).getId();

}

}

(4) control层,control类中添加@EnableAsync注解

packagecom.cfj.ceshi.async.web;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.scheduling.annotation.EnableAsync;importorg.springframework.web.bind.annotation.PostMapping;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RestController;importcom.cfj.ceshi.async.domain.UserInfo;importcom.cfj.ceshi.async.service.OrderService;importcom.cfj.ceshi.async.service.UserService;

@EnableAsync

@RestController

@RequestMapping("/tesasyc")public classAsycWeb {

@Autowired

UserService userService;

@Autowired

OrderService orderService;/*** 请使用 postman测试 方式选择posthttp://localhost:8081/tesasyc/save-one

* body 中选择form-data 或者x-wwww-form-urlencoded 输入对应键值对

*@paramname

*@paramage

*@return

*/@PostMapping(value= "/save-one") //相当于@RequestMapping(value = "/save-one", method = RequestMethod.POST)

publicString postOne(String name,String age) {

UserInfo user= newUserInfo();

user.setUserName(name);

user.setAge(age);

Integer id=userService.save(user);

orderService.saveOrder(id,name);returnid.toString();

}

}

fcb329dc7520486df64aac08ddef2fb2.png

参考:https://www.cnblogs.com/memoryXudy/p/7737418.html

https://segmentfault.com/a/1190000013974727

https://www.cnblogs.com/andyfengzp/p/6824253.html

https://www.cnblogs.com/benefitworld/p/5877423.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值