1. 程式人生 > >【java框架】SpringBoot(4)--SpringBoot實現非同步、郵件、定時任務

【java框架】SpringBoot(4)--SpringBoot實現非同步、郵件、定時任務

1.SpringBoot整合任務機制

1.1.SpringBoot實現非同步方法

日常開發中涉及很多介面與後端的互動響應,都不是同步的,基於SpringBoot為我們提供了註解方式實現非同步方法。使得前端的請求響應與後端的業務邏輯方法實現非同步執行。提升了客戶的體驗。不由得說一句,SpringBoot的封裝的確是精妙強大,以前需要多執行緒、Ajax實現非同步,而SpringBoot底層封裝之後,兩個註解就Over了!

①需要在SpringApplication執行類上開啟非同步,使用@EnableAsync:

@SpringBootApplication
@EnableAsync  //開啟非同步
public class SpringtestApplication {

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

}

 

②同時在執行呼叫耗時的方法上加上@Async表示該方法是非同步方法:

@Service
public class AsyncService {
    @Async
    public void execute(){
        try {
            Thread.sleep(3000);  //執行系統耗時任務
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("任務執行成功!");
    }
}

 

③那麼執行Controller層的呼叫非同步方法時就會非同步去執行方法,得到響應“success”返回而同時非同步執行後臺耗時方法:

@RestController
public class AsyncController {
    @Autowired
    private AsyncService service;

    @RequestMapping("/execute")
    public String executeTask(){
        service.execute();  //非同步執行3s
        return "success";   //非同步返回結果
    }
}

 

1.2.SpringBoot實現郵件傳送

Spring Boot中傳送郵件具體的使用步驟如下

1、新增Starter模組依賴

2、新增Spring Boot配置(QQ/網易系/Gmail)

3、呼叫JavaMailSender介面傳送郵件

 

①在pom.xml中新增郵件傳送starter依賴:

<!--郵件傳送-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>

 

②對應QQ郵箱傳送,去QQ郵箱客戶端開啟POP3/SMTP服務,獲取授權碼:

 

③新增配置引數,在application.yml中配置郵箱傳送方式:

QQ郵箱:

# QQ郵箱配置
spring:
  mail:
    host: smtp.qq.com #傳送郵件伺服器
    username: 241667****@qq.com #傳送郵件的郵箱地址
    password: ************ #客戶端授權碼,不是郵箱密碼,這個在qq郵箱設定裡面自動生成的
    properties.mail.smtp.port: 465 #埠號465或587
    from: 241667****@qq.com # 傳送郵件的地址,和上面username一致
    protocol: smtps  #如果使用埠為465,將protocol的smtp改為smtps;配置檔案埠為587,則可以使用smtp。
  #開啟加密驗證
  properties.mail.smtp.ssl.enable: true

 

網易郵箱:

##網易系(126/163/yeah)郵箱配置
spring:
  mail:
    host: smtp.163.com #傳送郵件伺服器
    username: hyfmail****@163.com #傳送郵件的郵箱地址
    password: ************ #客戶端授權碼,不是郵箱密碼,網易的是自己設定的
    properties.mail.smtp.port: 465 #465或者994
    from: hyfmail****@163.com # 傳送郵件的地址,和上面username一致
    properties.mail.smtp.ssl.enable: true
    default-encoding: utf-8

 

④編寫郵件傳送介面,實現類:

public interface IMailService {
    /**
     * 傳送文字郵件
     * @param to 收件人
     * @param subject 主題
     * @param content 內容
     */
    void sendSimpleMail(String to, String subject, String content);

    /**
     * 傳送HTML郵件
     * @param to 收件人
     * @param subject 主題
     * @param content 內容
     */
    public void sendHtmlMail(String to, String subject, String content);

    /**
     * 傳送帶附件的郵件
     * @param to 收件人
     * @param subject 主題
     * @param content 內容
     * @param filePath 附件
     */
    public void sendAttachmentsMail(String to, String subject, String content, String filePath);
}

 

@Service
public class MailServiceImpl implements IMailService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * Spring Boot 提供了一個傳送郵件的簡單抽象,使用的是下面這個介面,這裡直接注入即可使用
     */
    @Autowired
    private JavaMailSenderImpl mailSender;

    /**
     * 配置檔案中我的qq郵箱
     */
    @Value("${spring.mail.from}")
    private String from;

    @Override
    public void sendSimpleMail(String to, String subject, String content) {
        //建立SimpleMailMessage物件
        SimpleMailMessage message = new SimpleMailMessage();
        //郵件傳送人
        message.setFrom(from);
        //郵件接收人
        message.setTo(to);
        //郵件主題
        message.setSubject(subject);
        //郵件內容
        message.setText(content);
        //傳送郵件
        mailSender.send(message);
    }

    /**
     * html郵件
     * @param to 收件人
     * @param subject 主題
     * @param content 內容
     */
    @Override
    public void sendHtmlMail(String to, String subject, String content) {
        //獲取MimeMessage物件
        MimeMessage message = mailSender.createMimeMessage();
        MimeMessageHelper messageHelper;
        try {
            messageHelper = new MimeMessageHelper(message, true);
            //郵件傳送人
            messageHelper.setFrom(from);
            //郵件接收人
            messageHelper.setTo(to);
            //郵件主題
            message.setSubject(subject);
            //郵件內容,html格式
            messageHelper.setText(content, true);
            //傳送
            mailSender.send(message);
            //日誌資訊
            logger.info("郵件已經發送。");
        } catch (MessagingException e) {
            logger.error("傳送郵件時發生異常!", e);
        }
    }

    /**
     * 帶附件的郵件
     * @param to 收件人
     * @param subject 主題
     * @param content 內容
     * @param filePath 附件
     */
    @Override
    public void sendAttachmentsMail(String to, String subject, String content, String filePath) {
        MimeMessage message = mailSender.createMimeMessage();
        try {
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setFrom(from);
            helper.setTo(to);
            helper.setSubject(subject);
            helper.setText(content, true);

            FileSystemResource file = new FileSystemResource(new File(filePath));
            String fileName = filePath.substring(filePath.lastIndexOf(File.separator));
            helper.addAttachment(fileName, file);
            mailSender.send(message);
            //日誌資訊
            logger.info("郵件已經發送。");
        } catch (MessagingException e) {
            logger.error("傳送郵件時發生異常!", e);
        }
    }
}

 

⑤編寫測試類:

@SpringBootTest(classes = {SendmailApplication.class})
@RunWith(SpringRunner.class)
public class MailAppTest {

    @Autowired
    private IMailService mailService;

    /**
     * 測試傳送文字郵件
     */
    @Test
    public void testSendMail() {
        mailService.sendSimpleMail("[email protected]","主題:你好普通郵件","內容:第一封郵件");
    }

    /**
     * 測試傳送Html郵件
     */
    @Test
    public void sendHtmlMail(){
        mailService.sendHtmlMail("[email protected]","主題:你好html郵件","<h1>內容:第一封html郵件</h1>");
    }

    @Test
    public void sendMimeContentMail(){
        mailService.sendAttachmentsMail("[email protected]", "主題:你好複雜帶附件郵件",
                "<p style='color:red'>謝謝你的html郵件及問候~</p>", "E:\\Workspaces\\SpringBoot_Study\\springboot_test\\src\\main\\resources\\static\\1.jpg");
    }
}

 

1.3.定時任務

SpringBoot中執行定時任務主要用到有兩個重要介面與兩個任務排程的註解:

  • TaskScheduler    任務排程者
  • TaskExecutor    任務執行者
  • @EnableScheduling    開啟定時功能的註解
  • @Scheduled    用於在需要定時執行的方法上,表示在某一時刻定時執行

 

對應註解使用如下:

啟動類:

@SpringBootApplication
@EnableAsync  //開啟非同步
@EnableScheduling  //開啟定時功能的註解
public class SpringtestApplication {

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

}

 

啟動方法:

@Service
public class ScheduleService {
    //定時執行註解@Scheduled,需要使用cron表示式進行定時任務執行
    //表示每天下午13:43觸發
    @Scheduled(cron = "0 43 13 ? * *")
    public void timeExecute(){
        System.out.println("該任務被觸發執行了~~~");
    }
}

 

啟動SpringBoot專案,SpringBoot則會開啟定時任務執行並掃描方法上需要定時執行的註解,去定時執行相關的任務。

 

常用cron表示式如下:

0 0 2 1 * ? 表示在每月的1日的凌晨2點調整任務

0 15 10 ? * MON-FRI 表示週一到週五每天上午10:15執行作業

0 15 10 ? 6L 2002-2006 表示2002-2006年的每個月的最後一個星期五上午10:15執行作

0 0 10,14,16 * * ? 每天上午10點,下午2點,4點

0 0/30 9-17 * * ? 朝九晚五工作時間內每半小時

0 0 12 ? * WED 表示每個星期三中午12點

0 0 12 * * ? 每天中午12點觸發

0 15 10 ? * * 每天上午10:15觸發

0 15 10 * * ? 每天上午10:15觸發

0 15 10 * * ? 每天上午10:15觸發

0 15 10 * * ? 2005 2005年的每天上午10:15觸發

0 * 14 * * ? 在每天下午2點到下午2:59期間的每1分鐘觸發

0 0/5 14 * * ? 在每天下午2點到下午2:55期間的每5分鐘觸發

0 0/5 14,18 * * ? 在每天下午2點到2:55期間和下午6點到6:55期間的每5分鐘觸發

0 0-5 14 * * ? 在每天下午2點到下午2:05期間的每1分鐘觸發

0 10,44 14 ? 3 WED 每年三月的星期三的下午2:10和2:44觸發

0 15 10 ? * MON-FRI 週一至週五的上午10:15觸發

0 15 10 15 * ? 每月15日上午10:15觸發

0 15 10 L * ? 每月最後一日的上午10:15觸發

0 15 10 ? * 6L 每月的最後一個星期五上午10:15觸發

0 15 10 ? * 6L 2002-2005 2002年至2005年的每月的最後一個星期五上午10:15觸發

0 15 10 ? * 6#3 每月的第三個星期五上午10:15觸發

 

更多cron表示式請參閱:

https://www.jianshu.com/p/b4b8950fb987    《簡書--cron表示式》

https://www.matools.com/cron  《crom線上表示式生成器》

 

本部落格寫作參考文件相關:

https://www.jianshu.com/p/a7097a21b42d

https://blog.csdn.net/SixthMagnitude/article/details/114173570

https://www.bilibili.com/video/BV1PE411i7CV?p=52

https://www.jianshu.com/p/b4b8950fb987    《簡書--cron表示式》

https://www.matools.com/cron  《crom線上表示式生成器》

 

示例程式碼已上傳至Github地址:

https://github.com/devyf/SpringBoot_Study/tree/master/helloword_cr