SpringBoot使用Quartz定時器實現Email資訊轟炸

Chasing stars發表於2020-10-28

1、SpringBoot整合Quartz

1.Quartz簡介

Quartz是OpenSymphony開源組織在Job scheduling領域又一個開源專案,它可以與J2EE與J2SE應用程式相結合也可以單獨使用。Quartz可以用來建立簡單或為執行十個,百個,甚至是好幾萬個Jobs這樣複雜的程式。Jobs可以做成標準的Java元件或 EJBs。 (百度百科)

2.引入依賴

        <!-- quartz 定時器 -->
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.2.3</version>
        </dependency>

3.兩種方法配置定時器

第一種:

在 resources 下配置 spring-mvc.xml
程式碼如下:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:task="http://www.springframework.org/schema/task"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.2.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/task
       http://www.springframework.org/schema/task/spring-tack.xsd
       ">

    <context:annotation-config/>
        <!-- 利用 import 引入定時器的檔案 -->
    <import resource="spring-quartz.xml"/>

</beans>

在 resources 下配置 spring-quartz.xml
程式碼如下:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       ">
    <!-- 定義Job物件 -->
    <bean id="taskJob" class="com.example.demojpa.quartz.TestTask"/>
    <!--  定義JobDetail 物件 -->
    <bean id="JobDetail"
          class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <!-- 目標物件tackJob -->
        <property name="targetObject">
            <ref bean="taskJob"/>
        </property>
        <!-- 目標方法 -->
        <property name="targetMethod">
            <value>run</value>
        </property>
    </bean>

    <!-- 排程觸發器 -->
    <bean id="myTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <!-- 指定使用jobDetail -->
        <property name="jobDetail">
            <ref bean="JobDetail"/>
        </property>
        <!-- 定義觸發規則,每60秒執行一次 -->
        <property name="cronExpression">
            <value>0/60 * * * * ?</value>
        </property>
    </bean>

    <!-- 排程工廠 -->
    <bean id="schedules" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <!-- 註冊觸發器,可註冊多個 -->
        <property name="triggers">
            <list>
                <ref bean="myTrigger"/>
            </list>
        </property>
    </bean>
</beans>

在與service同級的目錄下建立資料夾quartz,在裡面建立一個類TestTask
程式碼如下:

package com.example.demojpa.quartz;

import org.apache.logging.log4j.*;
/*
* 定時器類
* ye
* 2020.10.27
* */
public class TestTask {
    //日誌物件
    private static final Logger logger = LogManager.getLogger(TestTask.class);

    public void run(){
        logger.info("定時器執行了!!!");
    }
}

第二種:

在 resources 下配置 spring-mvc.xml
程式碼如下:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:task="http://www.springframework.org/schema/task"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.2.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/task
       http://www.springframework.org/schema/task/spring-tack.xsd
       ">

    <context:annotation-config/>
        <!-- 利用 import 引入定時器的檔案 -->
    <import resource="spring-quartz.xml"/>

</beans>

在與service同級的目錄下建立資料夾quartz,在裡面建立一個類SendMailQuartz
程式碼如下:

package com.example.demojpa.quartz;

import com.example.demojpa.mail.SendJunkMailService;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.apache.logging.log4j.*;
import com.example.demojpa.service.AyUserService;
import javax.annotation.Resource;
import java.util.List;
import com.example.demojpa.model.AyUser;
/*
* 定時器
* ye
* 2020.10.27
*
* */
@Component
@Configurable
@EnableScheduling
public class SendMailQuartz {

    //日誌物件
    private static final Logger logger = LogManager.getLogger(SendMailQuartz.class);

    //每60秒執行一次
    @Scheduled(cron = "*/60 * * * *  *")
    public void reportCurrentByCron(){
        logger.info("定時器執行了!!!");
    }
}

同時在入口類,xxxApplication 加入@ImportResource註解

@SpringBootApplication
@ServletComponentScan
@ImportResource(locations = {"classpath:spring-mvc.xml"})
public class DemojpaApplication {

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

}

4.測試

我是兩種方法一起測試的
在這裡插入圖片描述
執行成功!

2、使用Quartz實現Email資訊轟炸

1.引入Mail的依賴

在pom.xml加入以下依賴

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

2.新增配置

在application.properties中加入相關配置

### Mail郵件配置
### 郵箱主機
spring.mail.host=smtp.qq.com
### 使用者名稱(你要登入的郵箱)
spring.mail.username=xxxx@qq.com
### 設定授權碼
spring.mail.password=xxxx

### 預設編碼
spring.mail.default-encoding=UTF-8
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties..mail.smtp.starttls.enable=true
spring.mail.properties..mail.smtp.starttls.required=true

3.在quartz中發生郵件

第一步:
在於service同級的目錄下建立mail資料夾,新建介面服務類SendJunkMailService,程式碼如下:

package com.example.demojpa.mail;
import java.util.List;
import com.example.demojpa.model.AyUser;
/*
* 傳送使用者郵件服務介面
* ye
* 2020.10.28
* */
public interface SendJunkMailService {
    //AyUser的作用只是為了獲取名字,可以省略
    boolean sendJunkMail(List<AyUser> ayUsers);
}

第二步:
繼續在該資料夾加新建以下impl資料夾,並新建實現類SendJunkMailServiceImpl,程式碼如下:

package com.example.demojpa.mail.impl;

import com.example.demojpa.mail.SendJunkMailService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import com.example.demojpa.service.AyUserService;
import javax.annotation.Resource;
import javax.mail.internet.MimeMessage;
import java.util.List;
import com.example.demojpa.model.AyUser;
/*
* 傳送郵件服務介面實現
* ye
* 2020.10.28
* */
@Service
public class SendJunkMailServiceImpl implements SendJunkMailService {
    @Autowired
    JavaMailSender mailSender;

    @Resource
    private AyUserService ayUserService;

    @Value("${spring.mail.username}")
    private String from;
    public static final Logger logger = LogManager.getLogger(SendJunkMailServiceImpl.class);

    @Override
    public boolean sendJunkMail(List<AyUser> ayUserList){
        try{
            if (ayUserList==null||ayUserList.size()<=0) return Boolean.FALSE;
            for (AyUser ayUser:ayUserList){
                MimeMessage mimeMessage = this.mailSender.createMimeMessage();
                MimeMessageHelper message = new MimeMessageHelper(mimeMessage);
                //郵件傳送方
                message.setFrom(from);
                //郵件主題
                message.setSubject("錄用通知");
                //郵件接收方
                message.setTo("xxxxx@qq.com");
                //郵件內容
                message.setText("恭喜您, "+ ayUser.getName() + ",您被錄用了!");
                //傳送郵件
                this.mailSender.send(mimeMessage);
            }
        }catch (Exception e){
            logger.error("sendJunkMail error and ayUser=%s",ayUserList,e);
            return Boolean.FALSE;
        }
        return Boolean.TRUE;
    }
}

第三步:
在我們開發的SendMailQuartz做一些修改:

package com.example.demojpa.quartz;

import com.example.demojpa.mail.SendJunkMailService;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.apache.logging.log4j.*;
import com.example.demojpa.service.AyUserService;
import javax.annotation.Resource;
import java.util.List;
import com.example.demojpa.model.AyUser;
/*
* 定時器
* ye
* 2020.10.27
*
* */
@Component
@Configurable
@EnableScheduling
public class SendMailQuartz {

    //日誌物件
    private static final Logger logger = LogManager.getLogger(SendMailQuartz.class);

    @Resource
    private SendJunkMailService sendJunkMailService;

    @Resource
    private AyUserService ayUserService;

    //每60秒執行一次
    @Scheduled(cron = "*/60 * * * *  *")
    public void reportCurrentByCron(){
        List<AyUser> userList = ayUserService.findAll();
        if (userList == null || userList.size() <= 0) return;;
        //傳送郵件
        sendJunkMailService.sendJunkMail(userList);
        logger.info("定時器執行了!!!");
    }
}

4.測試

在這裡插入圖片描述
我另一個郵箱收到了自己傳送的郵件,成功!

相關文章