博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring使用@Async注解异步处理
阅读量:6895 次
发布时间:2019-06-27

本文共 7745 字,大约阅读时间需要 25 分钟。

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类

package com.cfj.ceshi.async.domain;import java.io.Serializable;import java.util.Date;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.Table;@Entity@Table(name="order_table")public class OrderTable implements Serializable {            private static final long serialVersionUID = 1L;        @Id    @GeneratedValue(strategy = GenerationType.AUTO)    private Integer id;        @Column(name = "order_name")    private String orderName;        @Column(name = "user_id")    private Integer userId;         @Column(name = "create_date")    private Date createDate;    public Integer getId() {        return id;    }    public void setId(Integer id) {        this.id = id;    }    public String getOrderName() {        return orderName;    }    public void setOrderName(String orderName) {        this.orderName = orderName;    }    public Integer getUserId() {        return userId;    }    public void setUserId(Integer userId) {        this.userId = userId;    }    public Date getCreateDate() {        return createDate;    }    public void setCreateDate(Date createDate) {        this.createDate = createDate;    }                    }

 

package com.cfj.ceshi.async.domain;import java.io.Serializable;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.Table;@Entity@Table(name="user_info")public class UserInfo implements Serializable {    private static final long serialVersionUID = 1L;        @Id    @GeneratedValue(strategy = GenerationType.AUTO)    private Integer id;    private String userName;    private String age;    public Integer getId() {        return id;    }    public void setId(Integer id) {        this.id = id;    }    public String getUserName() {        return userName;    }    public void setUserName(String userName) {        this.userName = userName;    }    public String getAge() {        return age;    }    public void setAge(String age) {        this.age = age;    }    @Override    public String toString() {        return "UserInfo [id=" + id + ", userName=" + userName + ", age=" + age + "]";    }    }

 

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

package com.cfj.ceshi.async.repository;import org.springframework.data.jpa.repository.JpaRepository;import com.cfj.ceshi.async.domain.OrderTable;public interface OrderRepository extends JpaRepository
{}

 

package com.cfj.ceshi.async.repository;import org.springframework.data.jpa.repository.JpaRepository;import com.cfj.ceshi.async.domain.UserInfo;public interface UserRepository extends JpaRepository
{ }

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

package com.cfj.ceshi.async.service;public interface OrderService {        public void saveOrder(Integer UserId,String name);}
package com.cfj.ceshi.async.service;import java.util.List;import com.cfj.ceshi.async.domain.UserInfo;public interface UserService {        public Integer save(UserInfo user);        }
package com.cfj.ceshi.async.service.impl;import java.util.Date;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.scheduling.annotation.Async;import org.springframework.stereotype.Service;import com.cfj.ceshi.async.domain.OrderTable;import com.cfj.ceshi.async.repository.OrderRepository;import com.cfj.ceshi.async.service.OrderService;@Servicepublic class OrderServiceImpl implements OrderService {        @Autowired    OrderRepository orderRepository;        /**     * 异步保存     */    @Async    @Override    public void saveOrder(Integer UserId,String name) {        System.out.println("UserId:"+UserId);        System.out.println("=====" + Thread.currentThread().getName() + "=========");        OrderTable orderTable = new OrderTable();                orderTable.setOrderName(name+"订单");        orderTable.setUserId(UserId);        orderTable.setCreateDate(new Date());        orderRepository.save(orderTable);            }}
package com.cfj.ceshi.async.service.impl;import java.util.List;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;import com.cfj.ceshi.async.domain.UserInfo;import com.cfj.ceshi.async.repository.UserRepository;import com.cfj.ceshi.async.service.UserService;@Service@Transactionalpublic class UserServiceImpl implements UserService{            @Autowired    private UserRepository userRepository;        @Override    public Integer save(UserInfo user) {        System.out.println("=====" + Thread.currentThread().getName() + "=========");        return userRepository.save(user).getId();    }        }

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

package com.cfj.ceshi.async.web;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.scheduling.annotation.EnableAsync;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import com.cfj.ceshi.async.domain.UserInfo;import com.cfj.ceshi.async.service.OrderService;import com.cfj.ceshi.async.service.UserService;@EnableAsync@RestController@RequestMapping("/tesasyc")public class AsycWeb {        @Autowired    UserService userService;    @Autowired    OrderService orderService;                /**     *    请使用 postman测试    方式选择post  http://localhost:8081/tesasyc/save-one     *  body 中选择form-data 或者x-wwww-form-urlencoded  输入对应键值对     * @param name     * @param age     * @return     */    @PostMapping(value = "/save-one") //相当于@RequestMapping(value = "/save-one", method = RequestMethod.POST)    public String postOne(String name,String age) {        UserInfo user = new UserInfo();        user.setUserName(name);        user.setAge(age);        Integer id = userService.save(user);        orderService.saveOrder(id,name);        return id.toString();            }}

 

 

 

参考: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

 

转载于:https://www.cnblogs.com/kxm87/p/9290285.html

你可能感兴趣的文章
Java POI 解析word文档
查看>>
“如履薄冰”的游戏技能
查看>>
jQuery文字“橡皮圈“特效
查看>>
Mongo运行错误:Failed to connect 127.0.0.1:27017,reason:errno:10061由于目标计算机积极拒绝,无法连接...
查看>>
【Javascript】之动画加速
查看>>
学习进度条
查看>>
Batch Normalization&Dropout浅析
查看>>
Viewpager+fragment数据更新问题解析
查看>>
Display中getHeight()和getWidth() 官方废弃
查看>>
洛谷 P1525 关押罪犯==codevs 1069 关押罪犯[NOIP 2010]
查看>>
国密算法--Openssl 实现国密算法(加密和解密)
查看>>
经典智力题
查看>>
noip愤怒的小鸟&&vijos2008
查看>>
聚内核和微内核-转
查看>>
微软职位内部推荐-Principal DEV Manager for Bing Client
查看>>
for 循环
查看>>
Entity Framework技术系列之0:开篇
查看>>
201621123048《Java程序设计》第五周学习总结
查看>>
mac编辑器vim美化
查看>>
MD5摘要算法简析
查看>>