Spring中的异步任务

问题

项目中需要异步调用第三方服务,不需要关心是否调用成功。之前在文章《Spring task的异步定时任务》中使用的xml配置Spring Task的方式,而且之前是依靠时间触发异步的方式。这次在Spring boot项目中配置Spring Task,并且以代码直接调用异步方法的方式触发异步。

解决

配置异步

package com.zyl;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;

@SpringBootApplication
@EnableAsync
public class Application {

    public static void main(String[] args) {
        // close the application context to shut down the custom ExecutorService
        SpringApplication.run(Application.class, args).close();
    }

    @Bean
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(2);
        executor.setMaxPoolSize(2);
        executor.setQueueCapacity(500);
        executor.setThreadNamePrefix("Message-");
        executor.initialize();
        return executor;
    }


}

这里主要在Application.java类中,做了2处配置,一个是增加@EnableAsync注解,告诉Spring需要启用异步任务;二是添加了一个Bean,这个Bean主要就是配置异步调用的线程池的初始化参数。

model层

package com.zyl.model;

import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;

import javax.persistence.*;
import java.util.Date;

@Entity
public class Message {
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  @ApiModelProperty(notes = "主键", example = "0")
  private long id;

  /** 消息id */
  private String messageId;

  /** 消息标题 */
  private String messageTitle;

  /** 消息内容 */
  @Lob private String message;

  /** 发送人员 */
  private String uid;

  /** 发送时间 */
  @JsonFormat private Date sendTime;

  /** 消息结果 */
  @Lob private String messageResult;

  public long getId() {
    return id;
  }

  public void setId(long id) {
    this.id = id;
  }

  public String getMessage() {
    return message;
  }

  public void setMessage(String message) {
    this.message = message;
  }

  public String getUid() {
    return uid;
  }

  public void setUid(String uid) {
    this.uid = uid;
  }

  public Date getSendTime() {
    return sendTime;
  }

  public void setSendTime(Date sendTime) {
    this.sendTime = sendTime;
  }

  public String getMessageResult() {
    return messageResult;
  }

  public void setMessageResult(String messageResult) {
    this.messageResult = messageResult;
  }

  public String getMessageId() {
    return messageId;
  }

  public void setMessageId(String messageId) {
    this.messageId = messageId;
  }

  public String getMessageTitle() {
    return messageTitle;
  }

  public void setMessageTitle(String messageTitle) {
    this.messageTitle = messageTitle;
  }
}

这主要就是一个简单的Java Bean。

Service层

Service接口定义

package com.zyl.service;

import com.zyl.model.Message;
import org.springframework.scheduling.annotation.Async;

import java.util.Optional;

public interface IMessageService {

    /**
     * 推送一条消息
     * @param message 消息
     */
    @Async
    void pushMessage(Message message);
}

IMessageService是Service的接口定义。

Service接口实现

package com.zyl.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.hngytobacco.budget.model.Message;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.Optional;

@Service
public class MessageService implements IMessageService {

  private static final Logger logger = LoggerFactory.getLogger(MessageService.class);
    @Async
    @Override
    public void pushMessage(Message message) {
      logger.info("开始推送消息异步任务");
      try {
      // 模拟调用第三方推送消息接口延时
        Thread.sleep(1000L);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      logger.info("完成推送消息异步任务");
    }

}

MessageService是Service接口的具体实现,这里主要就是配置了@Async的异步注解,告诉Spring这是个异步方法,没有配置时间的方式触发。

Controller层

package com.zyl.controller;

import com.zyl.model.*;
import com.zyl.service.*;
import io.swagger.annotations.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping(value = "/message")
public class MessageController {
  private Logger logger = LoggerFactory.getLogger(MessageController.class);

  private final IMessageService messageService;

  @Autowired
  public BusinessController( IMessageService messageService) {
    this.messageService = messageService;
  }
  @GetMapping("/push")
  public ResponseEntity pushMessage(){
    Message message = new Message();
    logger.info("开始调用消息推送");
    messageService.pushMessage(message);
    logger.info("完成调用消息推送");
    return ResponseEntity.ok().build();
  }
}

效果

2019-05-09 16:10:58.429  INFO 28215 --- [nio-8081-exec-3] c.zyl.controller.MessageController      : 开始调用消息推送
2019-05-09 16:10:58.432  INFO 28215 --- [nio-8081-exec-3] c.zyl.controller.MessageController      : 完成调用消息推送
2019-05-09 16:10:58.432  INFO 28215 --- [      Message-1] c.zyl.service.MessageService        : 开始推送消息异步任务
2019-05-09 16:10:59.435  INFO 28215 --- [      Message-1] c.zyl.service.MessageService        : 完成推送消息异步任务

参考

转载于:https://my.oschina.net/fxtxz2/blog/3047539

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值