10.异步调用

1.异步调用简介
异步调用是相对于同步调用而言的,同步调用是指程序按预定顺序一步一步执行,每一步必须等到上一步执行完成之后才能执行,而异步调用则无需等待上一步程序执行完成即可执行。在日常开发的项目中,当访问的接口较慢或者做耗时任务时,避免程序一直卡在耗时任务上,使程序能够并行执行,可以使用多线程来并行处理,也可以使用SpringBoot提供的异步处理方式@Async来处理。

2.引入依赖
新建一个SpringBoot工程,并在pom.xml文件中添加需要的dependency。

<dependency>
    <groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
	<groupId>org.mybatis.spring.boot</groupId>
	<artifactId>mybatis-spring-boot-starter</artifactId>
	<version>1.1.1</version>
</dependency>
<dependency>
	<groupId>org.projectlombok</groupId>
	<artifactId>lombok</artifactId>
	<version>1.18.2</version>
	<scope>provided</scope>
</dependency>

3.添加配置
在application.properties文件中添加如下配置信息。

############################################################
#
# MySQL配置
#
############################################################
### 连接信息
spring.datasource.url = jdbc:mysql://localhost:3306/mydb
### 用户名
spring.datasource.username = root
### 密码
spring.datasource.password = admin123
### 驱动
spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver

############################################################
#
# MyBatis配置
#
############################################################
### po类存放目录
mybatis.type-aliases-package = com.leichuangkj.async.dao.po
### mapper(.xml)资源文件存放路径
mybatis.mapper-locations = classpath:mybatis/mapper/*.xml

spring.aop.proxy-target-class = true

4.dao层开发
首先在项目目录“/src/main/java/com/leichuangkj/async”下新建“/dao/po”目录,并在po目录下新建User实体类,具体代码如下。

@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class User {
    private Integer id;

    private String name;

    private String email;
}

然后在dao目录下新建mapper目录,并在mapper目录下新建UserMapper接口,具体代码如下。

@Repository
public interface UserMapper {
    List<User> findAll();
}

最后在resource目录下新建“mybatis/mapper”目录,并在mapper目录下新建UserMapper.xml文件,具体代码如下。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.leichuangkj.async.dao.mapper.UserMapper" >
    <resultMap id="BaseResultMap" type="com.leichuangkj.async.dao.po.User">
        <constructor>
            <idArg column="id" javaType="java.lang.Integer" jdbcType="INTEGER" />
            <arg column="name" javaType="java.lang.String" jdbcType="VARCHAR" />
            <arg column="email" javaType="java.lang.String" jdbcType="VARCHAR" />
        </constructor>
    </resultMap>
    <select id="findAll" resultMap="BaseResultMap">
        select  id, name, email
        from user
    </select>
</mapper>

5.service层开发
在项目目录“/src/main/java/com/leichuangkj/async”下新建service目录,并在service目录下新建IUser接口,具体代码如下。

public interface IUser {
    List<User> findAllSync() ;

    Future<List<User>> findAllAsync();
}

然后在service目录下新建impl目录,并在impl目录下新建UserImpl实现类,具体代码如下。

@Service
public class UserImpl implements IUser {
    @Autowired
    UserMapper userMapper;

    @Override
    public List<User> findAllSync() {
        try {
            System.out.println("开始做任务");
            long start = System.currentTimeMillis();
            List<User> userList = userMapper.findAll();
            long end = System.currentTimeMillis();
            System.out.println("完成任务,耗时:" + (end - start)+"毫秒");
            return userList;
        }catch (Exception e){
            return Collections.emptyList();
        }
    }

    @Async
    @Override
    public Future<List<User>> findAllAsync() {
        try {
            System.out.println("开始做任务");
            long start = System.currentTimeMillis();
            List<User> userList = userMapper.findAll();
            long end = System.currentTimeMillis();
            System.out.println("完成任务,耗时:" + (end - start)+"毫秒");
            return new AsyncResult<>(userList);
        }catch (Exception e){
            return new AsyncResult<>(null);
        }
    }
}

6.controller层开发
在项目目录“/src/main/java/com/leichuangkj/async”下新建controller目录,并在controller目录下新建UserController类,具体代码如下。

@Controller
@RequestMapping("/user")
public class UserController {
    @Autowired
    UserImpl userImpl;

    @RequestMapping(value = "/findAllSync",method = RequestMethod.GET)
    public void findAllSync(){
        long start = System.currentTimeMillis();
        System.out.println("第一次查询所有用户");
        List<User> userList1 = userImpl.findAllSync();
        System.out.println("第二次查询所有用户");
        List<User> userList2 = userImpl.findAllSync();
        System.out.println("第三次查询所有用户");
        List<User> userList3 = userImpl.findAllSync();
        long end = System.currentTimeMillis();
        System.out.println("总共消耗:"+ (end - start) + "毫秒");
    }

    @RequestMapping(value = "/findAllAsync",method = RequestMethod.GET)
    public void findAllAsync() throws InterruptedException {
        long start = System.currentTimeMillis();
        System.out.println("第一次查询所有用户");
        Future<List<User>> userList1 = userImpl.findAllAsync();
        System.out.println("第二次查询所有用户");
        Future<List<User>> userList2 = userImpl.findAllAsync();
        System.out.println("第三次查询所有用户");
        Future<List<User>> userList3 = userImpl.findAllAsync();
        while(true){
            if(userList1.isDone()&&userList2.isDone()&&userList3.isDone()){
                break;
            }else{
                Thread.sleep(10);
            }
        }
        long end = System.currentTimeMillis();
        System.out.println("总共消耗:"+ (end - start) + "毫秒");
    }
}

7.启动项目
在启动类MyBatisApplication上添加注解“@MapperScan(basePackages = “com.leichuangkj.async.dao.mapper”)”和“@EnableAsync(proxyTargetClass = true)”,然后启动项目。

@MapperScan(basePackages = "com.leichuangkj.async.dao.mapper")
@SpringBootApplication
@EnableAsync(proxyTargetClass = true)
public class AsyncApplication {
	public static void main(String[] args) {
		SpringApplication.run(AsyncApplication.class, args);
	}
}

8.测试
启动项目,然后分别在postman中请求“http://localhost:8080/user/findAllSync”和“http://localhost:8080/user/findAllAsync”,可以在控制台看到相应的执行结果,测试结果如下图所示,可以看到同步执行三次查询耗时为988毫秒,异步执行三次查询耗时772毫秒,由此可见,异步调用速度比同步调用速度快。
在这里插入图片描述
在这里插入图片描述

9.工程目录结构
在这里插入图片描述

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值