Siga o deus maluco SpringBoot para integrar tarefas assíncronas, temporizadas e de e-mail + Maven para expandir MailUtils

Siga o deus louco SpringBoot para integrar tarefas assíncronas, de tempo e de e-mail

Prefácio de tarefa de e-mail assíncrono, cronometrado

Em nosso trabalho, costumamos usar tarefas de processamento assíncrono. Por exemplo, quando enviamos e-mails no site, o plano de fundo enviará e-mails. Nesse momento, o primeiro plano fará com que a resposta seja inativa. A resposta não será bem-sucedida até que o e-mail é enviado, então geralmente essas tarefas serão tratadas de uma maneira multi-threaded. Existem também algumas tarefas agendadas, como a necessidade de analisar as informações do log do dia anterior na madrugada de cada dia. Também existe o envio de e-mails. Que tal o antecessor do WeChat como serviço de e-mail? Como essas coisas são alcançadas? Na verdade, SpringBoot nos forneceu o suporte correspondente.É muito fácil para nós começar.Nós só precisamos habilitar algum suporte de anotação e configurar alguns arquivos de configuração! Vamos dar uma olhada ~

Última edição em 2020.3.26 Autor: mad God said

Tarefa assíncrona

1. Crie um servicepacote

2. Crie uma classe

AsyncService

O processamento assíncrono ainda é muito comum. Por exemplo, quando enviamos e-mails no site, o plano de fundo enviará e-mails. Nesse momento, a recepção fará com que a resposta seja inativa. A resposta não terá êxito até que o e-mail seja enviado, portanto, geralmente usamos métodos multithread. Lide com essas tarefas

Escreva um método, finja estar processando dados, use threads para definir alguns atrasos e simule a situação de espera síncrona;

@Service
public class AsyncService {
    
    

   public void hello(){
    
    
       try {
    
    
           Thread.sleep(3000);
      } catch (InterruptedException e) {
    
    
           e.printStackTrace();
      }
       System.out.println("业务进行中....");
  }
}

3. Escreva um controllerpacote

4. Escreva a AsyncControlleraula

Vamos escrever um Controllerteste

@RestController
public class AsyncController {
    
    

   @Autowired
   AsyncService asyncService;

   @GetMapping("/hello")
   public String hello(){
    
    
       asyncService.hello();
       return "success";
  }

}

5. Visite http://localhost:8080/hellopara testar, o sucesso aparece após 3 segundos, esta é a situação de espera síncrona.

Pergunta: Se quisermos que o usuário receba a mensagem diretamente, podemos usar o processamento multi-threaded em segundo plano, mas cada vez que precisamos escrever manualmente a implementação multi-threaded, é muito problemático, só precisamos usar um simples O jeito é adicionar uma anotação simples ao nosso método, da seguinte maneira:

6. Adicione @Asyncanotações ao método hello ;

//告诉Spring这是一个异步方法
@Async
public void hello(){
    
    
   try {
    
    
       Thread.sleep(3000);
  } catch (InterruptedException e) {
    
    
       e.printStackTrace();
  }
   System.out.println("业务进行中....");
}

SpringBoot irá abrir um pool de threads por si só e fazer chamadas! Mas para que essa anotação tenha efeito, também precisamos adicionar uma anotação ao programa principal para @EnableAsynchabilitar a função de anotação assíncrona;

@EnableAsync //开启异步注解功能
@SpringBootApplication
public class SpringbootTaskApplication {
    
    

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

7. Reinicie o teste, a página da web responde instantaneamente e o código de fundo ainda é executado!

Tarefa cronometrada

No desenvolvimento de projetos, muitas vezes precisamos realizar algumas tarefas cronometradas. Por exemplo, precisamos analisar as informações de registro do dia anterior no início da manhã de cada dia. O Spring nos fornece uma maneira de realizar o agendamento de tarefas de forma assíncrona e fornece duas interfaces .

  • TaskExecutorInterface (executor de tarefas)

  • TaskSchedulerInterface (agendador de tarefas)

Duas notas:

  • @EnableScheduling(Notas sobre a abertura da função de cronometragem)

  • @Scheduled(Quando será executado)

expressão cron:

Insira a descrição da imagem aqui
Insira a descrição da imagem aqui

Etapas do teste:

1. Crie umScheduledService

Existe um método hello em nós, ele precisa ser executado regularmente, como lidar com isso?

@Service
public class ScheduledService {
    
    
   
   //秒   分   时     日   月   周几
   //0 * * * * MON-FRI
   //注意cron表达式的用法;
   @Scheduled(cron = "0 * * * * 0-7")
   public void hello(){
    
    
       System.out.println("hello.....");
  }
}

2. Depois de escrever a tarefa de cronometragem aqui, precisamos adicionar a @EnableSchedulingfunção de ligar a tarefa de cronometragem ao programa principal

@EnableAsync //开启异步注解功能
@EnableScheduling //开启基于注解的定时任务
@SpringBootApplication
public class SpringbootTaskApplication {
    
    

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

}

3. Vamos entender a cronexpressão em detalhes ;

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

4. Expressões comumente usadas

10/2 * * * * ?   表示每2秒 执行任务
(10 0/2 * * * ?   表示每2分钟 执行任务
(10 0 2 1 * ?   表示在每月的1日的凌晨2点调整任务
(20 15 10 ? * MON-FRI   表示周一到周五每天上午10:15执行作业
(30 15 10 ? 6L 2002-2006   表示2002-2006年的每个月的最后一个星期五上午10:15执行作
(40 0 10,14,16 * * ?   每天上午10点,下午2点,4点
(50 0/30 9-17 * * ?   朝九晚五工作时间内每半小时
(60 0 12 ? * WED   表示每个星期三中午12点
(70 0 12 * * ?   每天中午12点触发
(80 15 10 ? * *   每天上午10:15触发
(90 15 10 * * ?     每天上午10:15触发
(100 15 10 * * ?   每天上午10:15触发
(110 15 10 * * ? 2005   2005年的每天上午10:15触发
(120 * 14 * * ?     在每天下午2点到下午2:59期间的每1分钟触发
(130 0/5 14 * * ?   在每天下午2点到下午2:55期间的每5分钟触发
(140 0/5 14,18 * * ?     在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
(150 0-5 14 * * ?   在每天下午2点到下午2:05期间的每1分钟触发
(160 10,44 14 ? 3 WED   每年三月的星期三的下午2:102:44触发
(170 15 10 ? * MON-FRI   周一至周五的上午10:15触发
(180 15 10 15 * ?   每月15日上午10:15触发
(190 15 10 L * ?   每月最后一日的上午10:15触发
(200 15 10 ? * 6L   每月的最后一个星期五上午10:15触发
(210 15 10 ? * 6L 2002-2005   2002年至2005年的每月的最后一个星期五上午10:15触发
(220 15 10 ? * 6#3   每月的第三个星期五上午10:15触发

Tarefa de correio

Há muitos e-mails enviados em nosso desenvolvimento diário, e isso Springboottambém nos ajudou a apoiar

  • O envio de correio precisa ser introduzidospring-boot-start-mail

  • Configuração automática SpringBootMailSenderAutoConfiguration

  • Definição de MailPropertiesconteúdo, configuração application.ymlde

  • Montagem automáticaJavaMailSender

  • Teste de envio de e-mail

teste:

1. Apresente a dependência de pom

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

Olhe para as dependências que ele apresenta, você pode ver jakarta.mail

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

2. Visualize a categoria de configuração automática:MailSenderAutoConfiguration

Insira a descrição da imagem aqui

Existe nesta classe bean,JavaMailSenderImpl

Insira a descrição da imagem aqui

Então vamos dar uma olhada no arquivo de configuração

@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. Arquivo de configuração:

[email protected]
spring.mail.password=你的qq授权码
spring.mail.host=smtp.qq.com


# qq需要配置ssl
spring.mail.properties.mail.smtp.ssl.enable=true

Obtenha o código de autorização: Configurações na caixa de correio QQ -> Conta -> Abrir serviços pop3 e smtp

Insira a descrição da imagem aqui

4. Teste de unidade de mola

@Autowired
JavaMailSenderImpl mailSender;

@Test
public void contextLoads() {
    
    
   //邮件设置1:一个简单的邮件
   SimpleMailMessage message = new SimpleMailMessage();
   message.setSubject("通知-明天来狂神这听课");
   message.setText("今晚7:30开会");

   message.setTo("[email protected]");
   message.setFrom("[email protected]");
   mailSender.send(message);
}

@Test
public void contextLoads2() throws MessagingException {
    
    
   //邮件设置2:一个复杂的邮件
   MimeMessage mimeMessage = mailSender.createMimeMessage();
   MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);

   helper.setSubject("通知-明天来狂神这听课");
   helper.setText("<b style='color:red'>今天 7:30来开会</b>",true);

   //发送附件
   helper.addAttachment("1.jpg",new File(""));
   helper.addAttachment("2.jpg",new File(""));

   helper.setTo("[email protected]");
   helper.setFrom("[email protected]");

   mailSender.send(mimeMessage);
}

Verifique a caixa de correio, o e-mail foi recebido com sucesso!

Precisamos apenas usar a Thymeleafcombinação de front-end e back-end para desenvolver nossas próprias funções de envio e recebimento de correio do site!

O endereço do vídeo de apoio para a explicação do deus louco https://www.bilibili.com/video/BV1PE411i7CV

Artigo de referência

Maven estende MailUtils

jarPacote de importação

        <!--javaMail-->
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>javax.mail-api</artifactId>
            <version>1.5.6</version>
        </dependency>
        <dependency>
            <groupId>com.sun.mail</groupId>
            <artifactId>javax.mail</artifactId>
            <version>1.5.3</version>
        </dependency>

MailUtils

package com.huang.util;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Properties;

/**
 * 发邮件工具类
 */
public final class MailUtils {
    
    
    private static final String USER = "[email protected]"; // 发件人称号,同邮箱地址
    private static final String PASSWORD = "XXXXXXXX"; // 如果是qq邮箱可以使户端授权码,或者登录密码

    /**
     *
     * @param to 收件人邮箱
     * @param text 邮件正文
     * @param title 标题
     */
    /* 发送验证信息的邮件 */
    public static boolean sendMail(String to, String text, String title){
    
    
        //String USER = "[email protected]"; // 发件人称号,同邮箱地址
        //String PASSWORD = "XXXXXXXX"; // 如果是qq邮箱可以使户端授权码,或者登录密码
        try {
    
    
            final Properties props = new Properties();
            props.put("mail.smtp.auth", "true");
            props.put("mail.smtp.host", "smtp.qq.com");

            // 发件人的账号
            props.put("mail.user", USER);
            //发件人的密码
            props.put("mail.password", PASSWORD);

            // 构建授权信息,用于进行SMTP进行身份验证
            Authenticator authenticator = new Authenticator() {
    
    
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
    
    
                    // 用户名、密码
                    String userName = props.getProperty("mail.user");
                    String password = props.getProperty("mail.password");
                    return new PasswordAuthentication(userName, password);
                }
            };
            // 使用环境属性和授权信息,创建邮件会话
            Session mailSession = Session.getInstance(props, authenticator);
            // 创建邮件消息
            MimeMessage message = new MimeMessage(mailSession);
            // 设置发件人
            String username = props.getProperty("mail.user");
            InternetAddress form = new InternetAddress(username);
            message.setFrom(form);

            // 设置收件人
            InternetAddress toAddress = new InternetAddress(to);
            message.setRecipient(Message.RecipientType.TO, toAddress);

            // 设置邮件标题
            message.setSubject(title);

            // 设置邮件的内容体
            message.setContent(text, "text/html;charset=UTF-8");
            // 发送邮件
            Transport.send(message);
            return true;
        }catch (Exception e){
    
    
            e.printStackTrace();
        }
        return false;
    }

    public static void main(String[] args) throws Exception {
    
     // 做测试用
        //MailUtils.sendMail("[email protected]","你好,这是一封测试邮件,无需回复。","测试邮件");
        MailUtils.sendMail("[email protected]","<a href='http://localhost:8080/student/toActivation?studentCode=f7bb5d312da540ee8f9687e3ebcf0fd1'>确认激活学生素质拓展管理系统</a>" +
                "<br>或者访问http://localhost:8080/student/toActivation?studentCode=f7bb5d312da540ee8f9687e3ebcf0fd1","测试邮件");
        System.out.println("发送成功");
    }

}


Nota

O código a seguir precisa ser modificado de acordo com sua própria situação

private static final String PASSWORD = "XXXXXXXX"; // 如果是qq邮箱可以使户端授权码,或者登录密码

Este é o código de autorização, você deve mantê-lo em mente e não divulgá-lo !!!

Como obter o código de autorização

Obtenha o código de autorização: Configurações na caixa de correio QQ -> Conta -> Abrir serviços pop3 e smtp

Insira a descrição da imagem aqui

Acho que você gosta

Origin blog.csdn.net/qq_40649503/article/details/109501564
Recomendado
Clasificación