问题
项目中需要异步调用第三方服务,不需要关心是否调用成功。之前在文章《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 : 完成推送消息异步任务