SpringBoot非官方教程 | 第二十三篇: 异步方法

6人阅读 评论(0) 收藏 举报
分类:

转载请标明出处: 
http://blog.csdn.net/forezp/article/details/71024169 
本文出自方志朋的博客

这篇文章主要介绍在springboot 使用异步方法,去请求github api.

创建工程

在pom文件引入相关依赖:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>

创建一个接收数据的实体:

@JsonIgnoreProperties(ignoreUnknown=true)
public class User {

    private String name;
    private String blog;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getBlog() {
        return blog;
    }

    public void setBlog(String blog) {
        this.blog = blog;
    }

    @Override
    public String toString() {
        return "User [name=" + name + ", blog=" + blog + "]";
    }

}

创建一个请求的 githib的service:

@Service
public class GitHubLookupService {

    private static final Logger logger = LoggerFactory.getLogger(GitHubLookupService.class);

    private final RestTemplate restTemplate;

    public GitHubLookupService(RestTemplateBuilder restTemplateBuilder) {
        this.restTemplate = restTemplateBuilder.build();
    }

    @Async
    public Future<User> findUser(String user) throws InterruptedException {
        logger.info("Looking up " + user);
        String url = String.format("https://api.github.com/users/%s", user);
        User results = restTemplate.getForObject(url, User.class);
        // Artificial delay of 1s for demonstration purposes
        Thread.sleep(1000L);
        return new AsyncResult<>(results);
    }

}

通过,RestTemplate去请求,另外加上类@Async 表明是一个异步任务。

开启异步任务:


@SpringBootApplication
@EnableAsync
public class Application extends AsyncConfigurerSupport {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(2);
        executor.setMaxPoolSize(2);
        executor.setQueueCapacity(500);
        executor.setThreadNamePrefix("GithubLookup-");
        executor.initialize();
        return executor;
    }

}

通过@EnableAsync开启异步任务;并且配置AsyncConfigurerSupport,比如最大的线程池为2.

测试

测试代码如下:

@Component
public class AppRunner implements CommandLineRunner {

    private static final Logger logger = LoggerFactory.getLogger(AppRunner.class);

    private final GitHubLookupService gitHubLookupService;

    public AppRunner(GitHubLookupService gitHubLookupService) {
        this.gitHubLookupService = gitHubLookupService;
    }

    @Override
    public void run(String... args) throws Exception {
        // Start the clock
        long start = System.currentTimeMillis();

        // Kick of multiple, asynchronous lookups
        Future<User> page1 = gitHubLookupService.findUser("PivotalSoftware");
        Future<User> page2 = gitHubLookupService.findUser("CloudFoundry");
        Future<User> page3 = gitHubLookupService.findUser("Spring-Projects");

        // Wait until they are all done
        while (!(page1.isDone() && page2.isDone() && page3.isDone())) {
            Thread.sleep(10); //10-millisecond pause between each check
        }

        // Print results, including elapsed time
        logger.info("Elapsed time: " + (System.currentTimeMillis() - start));
        logger.info("--> " + page1.get());
        logger.info("--> " + page2.get());
        logger.info("--> " + page3.get());
    }

}

启动程序,控制台会打印:

2017-04-30 13:11:10.351 INFO 1511 — [ GithubLookup-1] com.forezp.service.GitHubLookupService : Looking up PivotalSoftware 
2017-04-30 13:11:10.351 INFO 1511 — [ GithubLookup-2] com.forezp.service.GitHubLookupService : Looking up CloudFoundry 
2017-04-30 13:11:13.144 INFO 1511 — [ GithubLookup-2] com.forezp.service.GitHubLookupService : Looking up Spring-Projects

耗时:3908

分析:可以卡的前面2个方法分别在GithubLookup-1 和GithubLookup-2执行,第三个在GithubLookup-2执行,注意因为在配置线程池的时候最大线程为2.如果你把线程池的个数为3的时候,耗时减少。

如果去掉@Async,你会发现,执行这三个方法都在main线程中执行。耗时总结,如下:

2017-04-30 13:13:00.934 INFO 1527 — [ main] com.forezp.service.GitHubLookupService : Looking up PivotalSoftware 
2017-04-30 13:13:03.571 INFO 1527 — [ main] com.forezp.service.GitHubLookupService : Looking up CloudFoundry 
2017-04-30 13:13:04.865 INFO 1527 — [ main] com.forezp.service.GitHubLookupService : Looking up Spring-Projects

耗时:5261

通过这一个小的栗子,你应该对异步任务有了一定的了解。

参考资料

https://spring.io/guides/gs/async-method/

源码下载

https://github.com/forezp/SpringBootLearning

优秀文章推荐:

查看评论

使用jMock辅助单元测试

使用jMock辅助单元测试作者:冰云 时间:2004-04-16联系:icecloud(AT)sina.comBlog:http://icecloud.51.netjMock是Junit的一个增强库。...
  • icecloud
  • icecloud
  • 2004-04-19 19:07:00
  • 3824

SpringBoot非官方教程,异步方法

这篇文章主要介绍在springboot 使用异步方法,去请求github api. 创建工程 在pom文件引入相关依赖: dependency> groupId>...
  • ll666634
  • ll666634
  • 2018-01-14 21:57:01
  • 157

SpringBoot非官方教程 | 第一篇:构建第一个SpringBoot工程

spring boot 它的设计目的就是为例简化开发,开启了各种自动装配,你不想写各种配置文件,引入相关的依赖就能迅速搭建起一个web工程。它采用的是建立生产就绪的应用程序观点,优先于配置的惯例。可能...
  • forezp
  • forezp
  • 2017-04-22 00:03:14
  • 46876

SpringBoot非官方教程 | 终章:文章汇总

springboot非官方教程,可能最接近于官方的一个教程,大多数案例都来自于官方文档,为了更好的理解,加入了个人的改造。...
  • forezp
  • forezp
  • 2017-04-22 00:08:27
  • 66830

SpringBoot非官方教程 | 第九篇: springboot整合Redis

这篇文章主要介绍springboot整合redis,至于没有接触过redis的同学可以看下这篇文章:5分钟带你入门Redis。...
  • forezp
  • forezp
  • 2017-04-30 00:11:55
  • 31457

Android O中的快捷方式好微件更新

请点击此处输入图片描述   为何使用快捷方式和微件?   在 Android O 中,最受欢迎的功能之一是能够通过深层链接将应用的快捷方式和微件固定到启动器上。   快捷方式让用户可...
  • dongnaoAndroid
  • dongnaoAndroid
  • 2017-08-14 15:26:03
  • 89

SpringBoot非官方教程 | 第六篇:springboot整合mybatis

本文主要讲解如何在springboot下整合mybatis,并访问数据库。由于mybatis这个框架太过于流行,所以我就不讲解了。...
  • forezp
  • forezp
  • 2017-04-25 23:25:54
  • 33971

SpringBoot非官方教程 | 第二十篇: 处理表单提交

这篇文件主要介绍通过springboot 去创建和提交一个表单。创建工程涉及了 web,加上spring-boot-starter-web和spring-boot-starter-thymeleaf的...
  • forezp
  • forezp
  • 2017-04-30 16:54:28
  • 30945

SpringBoot非官方教程 | 第二十一篇: springboot集成JMS

springboot对JMS提供了很好的支持,对其做了起步依赖。构架工程创建一个springboot工程。...
  • forezp
  • forezp
  • 2017-04-30 16:58:03
  • 25440

SpringBoot非官方教程 | 第二十四篇: springboot整合docker

这篇文篇介绍,怎么为 springboot程序构建一个docker镜像。docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从Apache2.0协议开源。Docker 可以让开发者打包他们的...
  • forezp
  • forezp
  • 2017-04-30 17:09:38
  • 28090
    个人资料
    等级:
    访问量: 937
    积分: 175
    排名: 103万+
    文章存档