Spring boot17: asynchronous, scheduled, mail tasks

Keywords: Spring Boot

Asynchronous task

1. Create a service package

2. Create an AsyncService class

Asynchronous processing is still very common. For example, when we send mail on the website, the background will send mail. At this time, the foreground will cause the response to remain motionless. The response will not succeed until the mail is sent. Therefore, we generally use multithreading to process these tasks.

Write methods, pretend to be processing data, use threads to set some delays, and simulate synchronous waiting

@Service
public class AsyncService {

    public void hello(){
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Data processing....");
    }
}

3. Write controller package

4. Writing the AsyncController class

Let's write a Controller and test it

@RestController
public class AsyncController {

    @Autowired
    AsyncService asyncService;

    @RequestMapping("/hello")
    public String hello(){
        asyncService.hello(); // Stop for three seconds
        return "OK";
    }
}

5. Visit http://localhost:8080/hello After the test, OK appears after 3 seconds, which is the condition of synchronous waiting.

Problem: if we want users to get messages directly, we can use multithreading in the background, but it's too troublesome to manually write the multithreading implementation every time. We just need to use a simple method and add a simple annotation to our method, as follows:

6. Add @ Async annotation to hello method;

// Tell Spring that this is an asynchronous method
@Async
public void hello(){
    try {
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("Data processing....");
}

SpringBoot will open a thread pool and call it! However, to make this annotation effective, we also need to add an annotation @ EnableAsync on the main program to enable the asynchronous annotation function;

@EnableAsync // Enable asynchronous annotation
@SpringBootApplication
public class Springboot09AsyncApplication {

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

}

7. Restart the test, the web page responds instantly, and the background code is still executed!

Mail task

Mail sending is also very much in our daily development, and Springboot also supports us

  • Spring boot start mail needs to be introduced for mail sending
  • SpringBoot auto configuration MailSenderAutoConfiguration
  • Define the MailProperties content and configure it in application.yml
  • Auto assemble JavaMailSender
  • Test mail sending

Test:

1. Introducing pom dependency

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

Looking at the dependencies it introduces, you can see jakarta.mail

<dependency>
  <groupId>com.sun.mail</groupId>
  <artifactId>jakarta.mail</artifactId>
  <version>1.6.7</version>
  <scope>compile</scope>
</dependency>

2. View autoconfiguration class: MailSenderAutoConfiguration

There are bean s in this class, JavaMailSenderImpl

Then let's look at the configuration file

@ConfigurationProperties(
    prefix = "spring.mail"
)
public class MailProperties {
    private static final Charset DEFAULT_CHARSET;
    private String host;
    private Integer port;
    private String username;
    private String password;
    private String protocol = "smtp";
    private Charset defaultEncoding;
    private Map<String, String> properties;
    private String jndiName;
}

3. Profile:

spring.mail.username=1620972953@qq.com
spring.mail.password=eccvnqzboomveijb
spring.mail.host=smtp.qq.com
# qq requires ssl configuration
spring.mail.properties.mail.smtp.ssl.enabl=true

Get authorization code: set in QQ mailbox - > account - > Open pop3 and smtp services

4. Spring unit test

package com.edgar;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;

@SpringBootTest
class Springboot09AsyncApplicationTests {

    @Autowired
    JavaMailSenderImpl mailSender;
    @Test
    void contextLoads() {

        // A simple email~
        SimpleMailMessage mailMessage = new SimpleMailMessage();
        mailMessage.setSubject("Hello, little crazy God~");
        mailMessage.setText("Thank you for your crazy talk series~");

        mailMessage.setTo("1620972953@qq.com");
        mailMessage.setFrom("1620972953@qq.com");
        mailSender.send(mailMessage);

    }

    @Test
    void contextLoads2() throws MessagingException {

        // A complex email~
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        // assemble
        MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,true);

        helper.setSubject("Hello, little crazy God~plus");
        helper.setText("<p style='color:red'>Thank you for your crazy talk series~</p>",true);

        // enclosure
        helper.addAttachment("1.jpg",new File("C:\\Users\\86152\\Pictures\\tool\\1.jpg"));
        helper.addAttachment("2.jpg",new File("C:\\Users\\86152\\Pictures\\tool\\1.jpg"));
        helper.setTo("1620972953@qq.com");
        helper.setFrom("1620972953@qq.com");
        mailSender.send(mimeMessage);

    }
}

Check the mailbox and the mail is received successfully!

We only need to use Thymeleaf for front-end and back-end combination to develop our website mail sending and receiving function!

Timed task

During project development, we often need to perform some scheduled tasks. For example, we need to analyze the log information of the previous day in the early morning of each day. Spring provides us with a way to schedule tasks asynchronously and provides two interfaces.

  • TaskExecutor interface
  • TaskScheduler interface

Two notes:

  • @EnableScheduling
  • @Scheduled

cron expression explanation

Cron expression is a string separated by 5 or 6 spaces and divided into 6 or 7 fields. Each field represents a meaning. Cron has the following two syntax formats:

​ (1) Seconds Minutes Hours DayofMonth Month DayofWeek Year

​ (2)Seconds Minutes Hours DayofMonth Month DayofWeek

  

1, Structure

corn from left to right (separated by spaces): second minute hour date in month month date year in week

2, Meaning of each field

field Allowable value Allowed special characters
Seconds Integer from 0 to 59 , - * / four characters
Minutes Integer from 0 to 59 , - * / four characters
Hours Integer from 0 to 23 , - * / four characters
Date (DayofMonth) An integer from 1 to 31 (but you need to consider the number of days in your month) ,- * ? / L W C eight characters
Month Integer from 1 to 12 or JAN-DEC , - * / four characters
DayofWeek Integer from 1 to 7 or SUN-SAT (1=SUN) , - * ? / L C # eight characters
Year (optional, leave blank) (year) 1970~2099 , - * / four characters

matters needing attention:

Each field uses numbers, but the following special characters can also appear, which mean:

(1): indicates any value matching the field. If it is used in the Minutes field, it means that an event will be triggered every minute.

  (2)?: It can only be used in DayofMonth and DayofWeek domains. It also matches any value of the field, but it doesn't. Because DayofMonth and DayofWeek will affect each other. For example, if you want to trigger scheduling on the 20th of each month, no matter what day of the week the 20th is, you can only use the following expression: 13 13 15 20 *?, The last one can only use?, It cannot be used. If it is used, it will be triggered regardless of the day of the week. In fact, it is not the case.

(3) -: indicates the range. For example, using 5-20 in the Minutes field means that it is triggered every minute from 5 Minutes to 20 Minutes

(4) /: indicates that the trigger starts at the starting time, and then triggers every fixed time. For example, if 5 / 20 is used in the Minutes field, it means that it is triggered once every 5 Minutes, while 25, 45, etc. are triggered once respectively

(5): indicates that the enumeration values are listed. For example, using 5,20 in the Minutes field means that it is triggered every minute at 5 and 20 Minutes.

(6) l: indicates that it can only appear in the DayofWeek and DayofMonth domains. If 5L is used in the DayofWeek domain, it means that it is triggered on the last Thursday.

(7) W: indicates a valid working day (Monday to Friday). It can only appear in the DayofMonth field. The system will trigger an event on the latest valid working day from the specified date. For example, 5W is used in DayofMonth. If the 5th is Saturday, it will be triggered on the latest working day: Friday, i.e. the 4th. If the 5th is Sunday, it will be triggered on the 6th (Monday); If the 5th is one of Monday to Friday, it will be triggered on the 5th. On the other hand, w's recent search will not cross the month.

(8) LW: these two characters can be used together to indicate the last working day of a month, that is, the last Friday.

(9) #: used to determine the day of the week of each month. It can only appear in the DayofWeek field. For example, in 4#2, it means the second Wednesday of a month.

III. examples of common expressions

  (0)0/20 * * * * ? Indicates that the task is adjusted every 20 seconds

  (1)0 0 2 1 * ? Indicates that the task is adjusted at 2 a.m. on the 1st of each month

  (2)0 15 10 ? * MON-FRI means to perform work at 10:15 a.m. every day from Monday to Friday

  (3)0 15 10 ? 6L 2002-2006 means the last Friday of each month in 2002-2006 at 10:15 a.m

  (4)0 0 10,14,16 * * ? Every day at 10 a.m., 2 p.m. and 4 p.m

  (5)0 0/30 9-17 * * ? Every half an hour during nine to five working hours

  (6)0 0 12 ? * WED means 12 noon every Wednesday

  (7)0 0 12 * * ? Triggered at 12 noon every day

  (8)0 15 10 ? * * Triggered every morning at 10:15

  (9)0 15 10 * * ? Triggered every morning at 10:15

  (10)0 15 10 * * ? * Triggered every morning at 10:15

  (11)0 15 10 * * ? Triggered at 10:15 a.m. every day in 2005

  (12)0 * 14 * * ? Triggered every 1 minute between 2 p.m. and 2:59 p.m. every day

  (13)0 0/5 14 * * ? Triggered every 5 minutes between 2 p.m. and 2:55 p.m. every day

  (14)0 0/5 14,18 * * ? Triggered every 5 minutes between 2 p.m. and 2:55 p.m. and between 6 p.m. and 6:55 p.m

  (15)0 0-5 14 * * ? Triggered every 1 minute between 2 p.m. and 2:05 p.m. every day

  (16)0 10,44 14 ? 3 WED is triggered at 2:10 and 2:44 p.m. on Wednesday in March every year

  (17)0 15 10 ? * MON-FRI triggered at 10:15 am from Monday to Friday

  (18)0 15 10 15 * ? Triggered at 10:15 a.m. on the 15th of each month

  (19)0 15 10 L * ? Triggered at 10:15 a.m. on the last day of each month

  (20)0 15 10 ? * 6L triggered at 10:15 a.m. on the last Friday of each month

  (21)0 15 10 ? * 6L 2002-2005 triggered at 10:15 a.m. on the last Friday of each month from 2002 to 2005

  (22)0 15 10 ? * Triggered at 10:15 am on the third Friday of 6#3 each month

Test steps:

1. Create a ScheduledService

There is a hello method in us. It needs to be executed regularly. How to deal with it?

// Second minute hour day month week
// 0 * * * * MON-FRI
// Pay attention to the usage of cron expression;
@Scheduled(cron = "0/10 * * * * ?")
public void hello(){
    System.out.println("hello,You were executed~");
}

2. After writing the scheduled task here, we need to add @ enableshcheduling to the main program to enable the scheduled task function

@EnableAsync // Enable asynchronous annotation
@EnableScheduling // Notes for turning on the timing function
@SpringBootApplication
public class Springboot09AsyncApplication {

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

}

3. Let's learn more about the cron expression;

http://www.bejson.com/othertools/cron/

Posted by ec on Thu, 02 Dec 2021 11:30:32 -0800