SpringBoot使用@Async異步調用方法

1、業務場景,在使用阿里大魚發送短信時,不知因何原因,後端接口發送短信較耗時,前端請求後端接口很快出現請求錯誤,這跟前端設置的響應時間相關,可以讓前端增加時間,但這並不是一個好的解決方法。

2、解決方案 

使用異步調用阿里發送短信的方案。

3、啓動類添加註解

@EnableAsync // 開啓異步任務

4、異步調用,方法加註解  

@Async
package com.ahies.stm.app.synthesizes.sys.service.impl;

import com.ahies.stm.app.synthesizes.sys.entity.Message;
import com.ahies.stm.app.synthesizes.sys.mapper.MessageMapper;
import com.ahies.stm.app.synthesizes.sys.service.MessageService;
import com.ahies.stm.app.base.BaseServiceImpl;
import com.ahies.stm.app.util.AliSendMessageUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Future;


@Service
@Transactional
public class MessageServiceImpl extends BaseServiceImpl<MessageMapper, Message> implements MessageService {

    @Value("${accessKeyId}")
    private String accessKeyId;

    @Value("${accessKeySecret}")
    private String accessKeySecret;

    @Value("${templatecode.forgetpassword}")
    private String templatecode;

    @Value("${sign}")
    private String sign;
    /*
    * @Description: 異步調用有返回值的阿里發送短信的方法
    * @param  phone, code 
    * @return java.util.concurrent.Future<java.lang.Boolean>
    * @menu /
    * @status done
    */
    @Async
    @Override
    public Future<Boolean> sendMessage(String phone, String code) {
        Map<String, String> param = new HashMap<>();
        param.put("code", code);
        boolean flag = AliSendMessageUtils.sendMessage(accessKeyId, accessKeySecret, phone, templatecode, sign, param);
        return new AsyncResult<>(flag);
    }
}

4、後臺發送短信的接口

 

package com.ahies.stm.app.interactive.index;

import com.ahies.stm.app.base.BaseController;
import com.ahies.stm.app.constant.SysConstant;
import com.ahies.stm.app.synthesizes.staff.entity.Member;
import com.ahies.stm.app.synthesizes.staff.service.MemberService;
import com.ahies.stm.app.synthesizes.sys.entity.Message;
import com.ahies.stm.app.synthesizes.sys.service.MessageService;
import com.ahies.stm.app.util.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/interactive/index/login")
@CrossOrigin
public class MemberLoginController extends BaseController {



    @Autowired
    MessageService messageService;
    @Autowired
    RedissonClient redissonClient;
    @Value("${accessKeyId}")
    private String accessKeyId;

    @Value("${accessKeySecret}")
    private String accessKeySecret;

    @Value("${templatecode.forgetpassword}")
    private String templatecode;

    @Value("${sign}")
    private String sign;



   
    @RequestMapping("/authenticode")
    public ResponseResult<String> authenticode(@RequestParam(name = "phone") String phone,
                                               @RequestParam(name = "ckeckPhone", required = false) String ckeckPhone) {
        if (StringUtils.isNotBlank(ckeckPhone)) {
            QueryWrapper<Member> wrapper = new QueryWrapper<>();
            wrapper.lambda().eq(Member::getPhoneNum, phone);
            Member member = memberService.getOne(wrapper);
            if (null == member) {
                return ResponseResult.dataFailed(null, SysConstant.PHONE_NOT_EXITS);
            }
        }
        RBucket<String> rBucket = redissonClient.getBucket(SysConstant.AUTHENTICODE_KEY_PRE + phone);
        String authenticode = "";
        boolean flag = false;
        if (StringUtils.isBlank(rBucket.get())) {
            authenticode = String.valueOf((int) (Math.random() * 900000 + 100000));
            String content = "您本次服務的驗證碼爲" + authenticode + ",請在10分鐘內使用。請勿向他人透露您的驗證碼。";
            Map<String, String> param = new HashMap<>();
            param.put("code", authenticode);
            Future<Boolean> future = messageService.sendMessage(phone, authenticode);
            try {
                flag = future.get();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
//            flag = AliSendMessageUtils.sendMessage(accessKeyId, accessKeySecret, phone, templatecode, sign, param);
            Message message = Message.builder().phone(phone).code(authenticode).content(content)
                    .build();
            messageService.save(message);
            rBucket.set(authenticode, 10, TimeUnit.MINUTES);
        } else {
            authenticode = rBucket.get();
            rBucket.set(authenticode, 10, TimeUnit.MINUTES);
            flag = true;
        }

        if (flag) {
            return ResponseResult.dataSuccess(authenticode, SysConstant.SEND_SUCCESS);
        }
        return ResponseResult.dataFailed(authenticode, SysConstant.SEND_FAIL);

    }

 
   


}

 

發佈了231 篇原創文章 · 獲贊 46 · 訪問量 25萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章