Siga al dios loco SpringBoot para integrar tareas asincrónicas, de sincronización y de correo
Prólogo de la tarea de correo asíncrona, temporizada
En nuestro trabajo, a menudo utilizamos tareas de procesamiento asincrónico. Por ejemplo, cuando enviamos correos electrónicos en el sitio web, el fondo enviará correos electrónicos. En este momento, el primer plano hará que la respuesta esté inactiva. La respuesta no tendrá éxito hasta que el correo electrónico se envía, por lo que generalmente estas tareas se manejarán de una manera multiproceso. También hay algunas tareas programadas, como la necesidad de analizar la información del registro del día anterior en las primeras horas de la mañana de cada día. También está el envío de correos electrónicos. ¿Qué hay del predecesor de WeChat como servicio de correo electrónico? ¿Cómo se logran estas cosas? De hecho, SpringBoot nos ha proporcionado el soporte correspondiente. Es muy fácil para nosotros comenzar. ¡Solo necesitamos habilitar algún soporte de anotaciones y configurar algunos archivos de configuración! Echemos un vistazo ~
Última edición en 2020.3.26 Autor: Dios loco dijo
Tarea asincrónica
1. Crea un service
paquete
2. Crea una clase
AsyncService
El procesamiento asincrónico sigue siendo muy común. Por ejemplo, cuando enviamos correos electrónicos en el sitio web, el fondo enviará correos electrónicos. En este momento, la recepción hará que la respuesta esté inactiva. La respuesta no se realizará correctamente hasta que se envíe el correo electrónico. por lo que generalmente usamos métodos de subprocesos múltiples. Lidiar con estas tareas.
Escriba un método, pretenda estar procesando datos, use hilos para establecer algunos retrasos y simule la situación de espera sincrónica;
@Service
public class AsyncService {
public void hello(){
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("业务进行中....");
}
}
3. Escribe un controller
paquete
4. Escribe la AsyncController
clase
Vamos a escribir una Controller
prueba
@RestController
public class AsyncController {
@Autowired
AsyncService asyncService;
@GetMapping("/hello")
public String hello(){
asyncService.hello();
return "success";
}
}
5. Visita http://localhost:8080/hello
para probar, el éxito aparece después de 3 segundos, esta es la situación de espera sincrónica.
Pregunta: Si queremos que el usuario reciba el mensaje directamente, podemos usar el procesamiento de subprocesos múltiples en segundo plano, pero cada vez que necesitamos escribir manualmente la implementación de subprocesos múltiples, es demasiado problemático, solo necesitamos usar un simple La forma es agregar una anotación simple a nuestro método, de la siguiente manera:
6. Agregue @Async
anotaciones al método hello ;
//告诉Spring这是一个异步方法
@Async
public void hello(){
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("业务进行中....");
}
SpringBoot abrirá un grupo de subprocesos por sí mismo y hará llamadas. Pero para que esta anotación surta efecto, también necesitamos agregar una anotación al programa principal para @EnableAsync
habilitar la función de anotación asincrónica;
@EnableAsync //开启异步注解功能
@SpringBootApplication
public class SpringbootTaskApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootTaskApplication.class, args);
}
}
7. Reinicie la prueba, la página web responde instantáneamente y el código de fondo aún se ejecuta.
Tarea cronometrada
En el desarrollo de proyectos, a menudo necesitamos realizar algunas tareas cronometradas. Por ejemplo, necesitamos analizar la información de registro del día anterior temprano en la mañana de cada día. Spring nos proporciona una forma de realizar la programación de tareas de forma asincrónica y proporciona dos interfaces .
-
TaskExecutor
Interfaz (ejecutante de la tarea) -
TaskScheduler
Interfaz (programador de tareas)
Dos notas:
-
@EnableScheduling
(Notas sobre la apertura de la función de cronometraje) -
@Scheduled
(¿Cuándo se ejecutará?)
expresión cron:
Pasos de prueba:
1. Crea unoScheduledService
Hay un método de saludo en nosotros, debe ejecutarse regularmente, ¿cómo lidiar con él?
@Service
public class ScheduledService {
//秒 分 时 日 月 周几
//0 * * * * MON-FRI
//注意cron表达式的用法;
@Scheduled(cron = "0 * * * * 0-7")
public void hello(){
System.out.println("hello.....");
}
}
2. Después de escribir la tarea de cronometraje aquí, necesitamos agregar la @EnableScheduling
función de activar la tarea de cronometraje al programa principal
@EnableAsync //开启异步注解功能
@EnableScheduling //开启基于注解的定时任务
@SpringBootApplication
public class SpringbootTaskApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootTaskApplication.class, args);
}
}
3. Entendamos la cron
expresión en detalle ;
http://www.bejson.com/othertools/cron/
4. Expresiones de uso común
(1)0/2 * * * * ? 表示每2秒 执行任务
(1)0 0/2 * * * ? 表示每2分钟 执行任务
(1)0 0 2 1 * ? 表示在每月的1日的凌晨2点调整任务
(2)0 15 10 ? * MON-FRI 表示周一到周五每天上午10:15执行作业
(3)0 15 10 ? 6L 2002-2006 表示2002-2006年的每个月的最后一个星期五上午10:15执行作
(4)0 0 10,14,16 * * ? 每天上午10点,下午2点,4点
(5)0 0/30 9-17 * * ? 朝九晚五工作时间内每半小时
(6)0 0 12 ? * WED 表示每个星期三中午12点
(7)0 0 12 * * ? 每天中午12点触发
(8)0 15 10 ? * * 每天上午10:15触发
(9)0 15 10 * * ? 每天上午10:15触发
(10)0 15 10 * * ? 每天上午10:15触发
(11)0 15 10 * * ? 2005 2005年的每天上午10:15触发
(12)0 * 14 * * ? 在每天下午2点到下午2:59期间的每1分钟触发
(13)0 0/5 14 * * ? 在每天下午2点到下午2:55期间的每5分钟触发
(14)0 0/5 14,18 * * ? 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
(15)0 0-5 14 * * ? 在每天下午2点到下午2:05期间的每1分钟触发
(16)0 10,44 14 ? 3 WED 每年三月的星期三的下午2:10和2:44触发
(17)0 15 10 ? * MON-FRI 周一至周五的上午10:15触发
(18)0 15 10 15 * ? 每月15日上午10:15触发
(19)0 15 10 L * ? 每月最后一日的上午10:15触发
(20)0 15 10 ? * 6L 每月的最后一个星期五上午10:15触发
(21)0 15 10 ? * 6L 2002-2005 2002年至2005年的每月的最后一个星期五上午10:15触发
(22)0 15 10 ? * 6#3 每月的第三个星期五上午10:15触发
Tarea de correo
Hay muchos envíos de correo electrónico en nuestro desarrollo diario, y Springboot
también nos ayudó a respaldar
-
Es necesario introducir el envío de correo
spring-boot-start-mail
-
Configuración automática de SpringBoot
MailSenderAutoConfiguration
-
Definición de
MailProperties
contenido, configuraciónapplication.yml
de -
Montaje automático
JavaMailSender
-
Envío de correo de prueba
prueba:
1. Introducir la dependencia de pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
Mira las dependencias que presenta, puedes ver jakarta.mail
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>jakarta.mail</artifactId>
<version>1.6.4</version>
<scope>compile</scope>
</dependency>
2. Ver la categoría de configuración automática:MailSenderAutoConfiguration
Existe en esta clase bean
,JavaMailSenderImpl
Luego vamos a mirar el archivo de configuración
@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. Archivo de configuración:
[email protected]
spring.mail.password=你的qq授权码
spring.mail.host=smtp.qq.com
# qq需要配置ssl
spring.mail.properties.mail.smtp.ssl.enable=true
Obtenga el código de autorización: Configuración en el buzón de QQ -> Cuenta -> Abrir servicios pop3 y smtp
4. Prueba de la unidad de resorte
@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 el buzón, ¡el correo se recibió con éxito!
¡Solo necesitamos usar la Thymeleaf
combinación de front-end y back-end para desarrollar nuestras propias funciones de envío y recepción de correo en el sitio web!
La dirección de video de apoyo para la explicación del dios loco https://www.bilibili.com/video/BV1PE411i7CV
Articulo de referencia
Maven extiende MailUtils
Importar jar
paquete
<!--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
El siguiente código debe modificarse de acuerdo con su propia situación
private static final String PASSWORD = "XXXXXXXX"; // 如果是qq邮箱可以使户端授权码,或者登录密码
Este es el código de autorización, debes tenerlo en cuenta y no lo pierdas !!!
Cómo obtener el código de autorización
Obtenga el código de autorización: Configuración en el buzón de QQ -> Cuenta -> Abrir servicios pop3 y smtp