hocvietcode.com
  • Trang chủ
  • Học lập trình
    • Lập trình C/C++
    • Cấu trúc dữ liệu và giải thuật
    • Lập trình HTML
    • Lập trình Javascript
      • Javascript cơ bản
      • ReactJS framework
      • AngularJS framework
      • Typescript cơ bản
      • Angular
      • NodeJS
    • Lập trình Mobile
      • Lập Trình Dart Cơ Bản
        • Dart Flutter Framework
    • Cơ sở dữ liệu
      • MySQL – MariaDB
      • Micrsoft SQL Server
      • Extensible Markup Language (XML)
      • JSON
      • MongoDB
    • Lập trình PHP
      • Lập trình PHP cơ bản
      • Laravel Framework
    • Lập trình Java
      • Java Cơ bản
      • Spring Boot
    • Lập trình C#
      • Lập Trình C# Cơ Bản
      • ASP.NET Core MVC
    • Machine Learning
    • Git và Github
  • WORDPRESS
    • WordPress cơ bản
    • WordPress nâng cao
    • Chia sẻ WordPress
  • Kiến thức hệ thống
    • Microsoft Azure
    • Docker
    • Linux
  • Chia sẻ IT
    • Tin học văn phòng
      • Microsoft Word
      • Microsoft Excel
    • Marketing
      • Google Adwords
      • Facebook Ads
      • Kiến thức khác
    • Chia sẻ phần mềm
    • Review công nghệ
    • Công cụ – tiện ích
      • Kiểm tra bàn phím online
      • Kiểm tra webcam online
  • Lập trình Python
Đăng nhập
  • Đăng nhập / Đăng ký

Please enter key search to display results.

Home
  • Spring Boot
Spring Boot bài 24: Gửi email và lập lịch tác vụ trong Spring Boot
Java và Spring Boot – MVC và REST API

Spring Boot bài 24: Gửi email và lập lịch tác vụ trong Spring Boot

  • 18-10-2026
  • Toanngo92
  • 0 Comments

Giáo trình Spring Boot MVC và REST API · Chương 10/12: Tích hợp HTTP, email và lịch tác vụ · Bài 24/28 · Biên soạn tháng 10/2026.

← Bài 23 · Mục lục 12 chương · Bài 25 →

Mục lục

  • Mục tiêu bài học
  • Email là tích hợp bên ngoài
  • Service gửi thông điệp văn bản
  • Lập lịch với @Scheduled
  • Một lịch trong mỗi instance
  • Lỗi thường gặp và lưu ý
  • Ghi nhớ
  • Tài liệu đối chiếu

Mục tiêu bài học

Cấu hình SMTP qua môi trường, gửi email văn bản và hiểu giới hạn của @Scheduled khi triển khai.

Email là tích hợp bên ngoài

Gửi email cần SMTP server, tài khoản và chính sách của nhà cung cấp. Starter Mail cung cấp hạ tầng JavaMailSender, nhưng không tự tạo hộp thư hoặc đảm bảo thư đến inbox. DNS của tên miền, SPF/DKIM/DMARC, quota và uy tín gửi thư thuộc phần vận hành ngoài ví dụ Java.

Mẫu mặc định tắt email. Muốn thử, bật thêm profile mail, cung cấp HVC_SMTP_HOST, HVC_SMTP_PORT, HVC_SMTP_USER, HVC_SMTP_PASSWORD và HVC_MAIL_FROM. Cấu hình mẫu dùng cổng 587 với STARTTLS; nếu nhà cung cấp yêu cầu TLS kiểu khác, cần điều chỉnh theo tài liệu của họ thay vì giữ nguyên thông số này.

Tệp trong mã nguồn mẫu: src/main/resources/application-mail.properties. Đoạn dưới được trích từ tệp này; xem bản tải về để có đủ import và phần còn lại.

spring.mail.host=${HVC_SMTP_HOST}
spring.mail.port=${HVC_SMTP_PORT:587}
spring.mail.username=${HVC_SMTP_USER}
spring.mail.password=${HVC_SMTP_PASSWORD}
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.connectiontimeout=3000
spring.mail.properties.mail.smtp.timeout=5000
spring.mail.properties.mail.smtp.writetimeout=5000
hvc.mail.enabled=true
hvc.mail.from=${HVC_MAIL_FROM}

Service gửi thông điệp văn bản

CourseMail chỉ được tạo khi hvc.mail.enabled=true. Nó tạo SimpleMailMessage với người gửi, người nhận, tiêu đề và nội dung text. Bản mẫu chưa gắn gửi email tự động vào create để mỗi lần học CRUD không vô tình phát thư thật. Có thể gọi service từ một luồng nghiệp vụ được thiết kế riêng sau khi đã kiểm tra bằng SMTP thử hoặc mock.

Không nhận to và body tùy ý từ một endpoint công khai, vì có thể biến ứng dụng thành công cụ gửi spam. Khi gửi thư thông báo sau ghi DB, cần tính đến thời điểm transaction commit và chiến lược retry; gửi thành công rồi rollback dữ liệu sẽ tạo thông tin sai cho người nhận.

Tệp trong mã nguồn mẫu: src/main/java/com/hocvietcode/academy/CourseMail.java. Đoạn dưới được trích từ tệp này; xem bản tải về để có đủ import và phần còn lại.

package com.hocvietcode.academy;
import org.springframework.stereotype.Service;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.beans.factory.annotation.Value;
@Service @ConditionalOnProperty(name="hvc.mail.enabled",havingValue="true")
public class CourseMail {
    private final JavaMailSender sender; private final String from;
    public CourseMail(JavaMailSender sender,@Value("${hvc.mail.from}") String from){this.sender=sender;this.from=from;}
    public void sendReminder(String to,String title){
        SimpleMailMessage message=new SimpleMailMessage();message.setFrom(from);message.setTo(to);
        message.setSubject("Lịch học HVC Academy");message.setText("Mời bạn tiếp tục khóa học: "+title);
        sender.send(message);
    }
}

Lập lịch với @Scheduled

@EnableScheduling bật xử lý scheduled method. CourseSchedule chỉ được tạo khi hvc.reminders-enabled=true. Mỗi 8 giờ sáng theo Asia/Ho_Chi_Minh, tác vụ ghi tổng số khóa học vào log. Tên cấu hình nhắc lịch phục vụ hướng mở rộng, nhưng tác vụ hiện tại không gửi email tự động.

Cron của Spring có trường giây, nên chuỗi 0 0 8 * * * khác các ví dụ cron hệ điều hành chỉ có năm trường. Ghi rõ timezone để lịch không thay đổi theo múi giờ của máy triển khai. Các tác vụ dài cần kế hoạch pool, thời gian chạy và xử lý lỗi thay vì mặc định mọi việc sẽ tự chạy song song.

Tệp trong mã nguồn mẫu: src/main/java/com/hocvietcode/academy/CourseSchedule.java. Đoạn dưới được trích từ tệp này; xem bản tải về để có đủ import và phần còn lại.

package com.hocvietcode.academy;
import org.springframework.stereotype.Component;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.Scheduled;
import org.slf4j.*;
@Component @ConditionalOnProperty(name="hvc.reminders-enabled",havingValue="true")
public class CourseSchedule {
    private static final Logger log=LoggerFactory.getLogger(CourseSchedule.class);
    private final CourseRepository courses;
    public CourseSchedule(CourseRepository courses){this.courses=courses;}
    @Scheduled(cron="${hvc.reminder-cron:0 0 8 * * *}",zone="Asia/Ho_Chi_Minh")
    public void report(){log.info("Số khóa học đang có: {}",courses.count());}
}

Một lịch trong mỗi instance

Nếu chạy ba instance ứng dụng, @Scheduled có thể chạy ba lần. Nó không phải distributed scheduler và không tự bảo đảm chỉ thực hiện một lần trên toàn hệ thống. Với việc cần tính duy nhất, phải có khóa phân tán, job scheduler hoặc hệ thống queue phù hợp cùng thiết kế idempotent.

Test CourseMailTest chỉ xác nhận thông điệp được truyền đúng cho JavaMailSender giả lập, không gửi SMTP thật. Kiểm tra nhận thư thật nên làm bằng tài khoản và hộp nhận thử, tránh dùng email học viên. Cấu hình timeout SMTP giúp một dịch vụ ngoài bị treo không giữ luồng vô hạn.

Lỗi thường gặp và lưu ý

  • Không để mật khẩu SMTP trong bài viết, file nguồn hoặc Docker image.
  • Không coi @Scheduled là cơ chế chạy đúng một lần khi scale nhiều instance.

Ghi nhớ

Mail cần cấu hình và kiểm tra tích hợp riêng; scheduling cần timezone, kiểm soát trùng lặp và giới hạn thời gian.

Tài liệu đối chiếu

  • Email
  • Task Scheduling

← Bài 23 · Mục lục 12 chương · Bài 25 →

Bài viết liên quan:

Java và Spring Boot – MVC và REST API
Spring Boot bài 22: Validation API, ProblemDetail và hợp đồng lỗi
Java và Spring Boot – MVC và REST API
Spring Boot bài 23: Gọi dịch vụ HTTP bằng RestClient và đặt timeout
Java và Spring Boot – MVC và REST API
Spring Boot bài 08: Fragment, layout và tài nguyên CSS trong Spring Boot
Java và Spring Boot – MVC và REST API
Spring Boot bài 25: Unit test Service với JUnit và Mockito
Java và Spring Boot – MVC và REST API
Spring Boot bài 09: Binding biểu mẫu tạo và sửa khóa học
Java và Spring Boot – MVC và REST API
Spring Boot bài 26: Integration test MVC, API, database và Security
Java và Spring Boot – MVC và REST API
Spring Boot bài 10: Validation và BindingResult: báo lỗi ngay trên biểu mẫu
Java và Spring Boot – MVC và REST API
Spring Boot bài 27: Logging, Actuator và quản lý schema bằng Flyway
Java và Spring Boot – MVC và REST API
Spring Boot bài 11: Post/Redirect/Get, flash message và session
Java và Spring Boot – MVC và REST API
Spring Boot bài 28: Đóng gói JAR, Docker và cấu hình triển khai
Java và Spring Boot – MVC và REST API
Spring Boot bài 12: JPA Entity, Repository, H2 và migration đầu tiên
Java và Spring Boot – MVC và REST API
Giáo trình Spring Boot MVC và REST API 2026: 12 chương, 28 bài

Dịch vụ thiết kế Wesbite

NỘI DUNG MỚI CẬP NHẬT

Giáo trình Python: mục lục 12 chương, 24 bài từ cơ bản đến ứng dụng

Python bài 24: Lock, Queue và thiết kế worker an toàn

Python bài 23: Thread, start, join và concurrency

Python bài 22: Kết nối MySQL và CRUD có transaction

Python bài 21: Gọi HTTP API, xử lý JSON và tải dữ liệu

Giới thiệu

hocvietcode.com là website chia sẻ và cập nhật tin tức công nghệ, chia sẻ kiến thức, kỹ năng. Chúng tôi rất cảm ơn và mong muốn nhận được nhiều phản hồi để có thể phục vụ quý bạn đọc tốt hơn !

Liên hệ quảng cáo: [email protected]

Kết nối với HỌC VIẾT CODE

© hocvietcode.com - Tech888 Co .Ltd since 2019

Đăng nhập

Trở thành một phần của cộng đồng của chúng tôi!
Registration complete. Please check your email.
Đăng nhập bằng google
Đăng kýBạn quên mật khẩu?

Create an account

Welcome! Register for an account
The user name or email address is not correct.
Registration confirmation will be emailed to you.
Log in Lost your password?

Reset password

Recover your password
Password reset email has been sent.
The email could not be sent. Possible reason: your host may have disabled the mail function.
A password will be e-mailed to you.
Log in Register
×