Sending Async Emails in Spring

I have a student taking my course that sent me the following question
It would be really cool to show how to send this email asynchronously. Because it's never a good idea to send any sort of notification synchronously.
I do agree with him in that there is no reason for us block program execution for something like sending an email. I am going to take this chance to walk you through sending email asynchronously using Spring Boot. Start off by creating a basic new Spring Boot project using the Spring Initializr from the web or your favorite IDE. We are going to select Web & Mail as dependencies.
By selecting web and mail as dependencies we should have these two starter dependencies included included in our build file.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
With the starter mail dependency in place we need to configure our mail server properties.
spring.mail.host = smtp.gmail.com
spring.mail.username = [email protected]
spring.mail.password = xxxxxxxxxxxxxxxxxx
spring.mail.port=587
spring.mail.properties.mail.smtp.starttls.enable = true
The first thing we are going to do is create a controller. This controller is going to have a request mapping of signup-success. This method is going to create a user (just a simple POJO) and then try to send a notification using our notification service.
@RestController
public class RegistrationController {
private Logger logger = LoggerFactory.getLogger(RegistrationController.class);
@Autowired
private NotificationService notificationService;
@RequestMapping("/signup-success")
public String signupSuccess(){
// create user
User user = new User();
user.setFirstName("Dan");
user.setLastName("Vega");
user.setEmailAddress("[email protected]");
// send a notification
try {
notificationService.sendNotificaitoin(user);
}catch( Exception e ){
// catch error
logger.info("Error Sending Email: " + e.getMessage());
}
return "Thank you for registering with us.";
}
}
The Notification Service is where the real magic happens. At the start of our send notification method we are going to simulate a long process by using the sleep method. Notice that we have add the @Async annotation to the method that marks a method as a candidate for asynchronous execution.
@Service
public class NotificationService {
private JavaMailSender javaMailSender;
@Autowired
public NotificationService(JavaMailSender javaMailSender){
this.javaMailSender = javaMailSender;
}
@Async
public void sendNotificaitoin(User user) throws MailException, InterruptedException {
System.out.println("Sleeping now...");
Thread.sleep(10000);
System.out.println("Sending email...");
SimpleMailMessage mail = new SimpleMailMessage();
mail.setTo(user.getEmailAddress());
mail.setFrom("[email protected]");
mail.setSubject("Spring Boot is awesome!");
mail.setText("Why aren't you using Spring Boot?");
javaMailSender.send(mail);
System.out.println("Email Sent!");
}
}
We have one final task to make all of this work. Go to the main application class and add the @EnableAsync annotation.
package com.therealdanvega;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
@EnableAsync
public class SendingEmailAsyncApplication {
public static void main(String\[\] args) {
SpringApplication.run(SendingEmailAsyncApplication.class, args);
}
}
Start the application and go to http://localhost:8080/signup-success. You will see the message "Thank you for registering with us." right away and in the console you will see the Sleeping/Sending/Sent messages printed out to the console. If you aren't familiar with Async this is where the real power comes in. The program is not blocking a task like sending an email and returns execution to the user while it performs that task in the background.
You can grab the source for this application below.
https://github.com/danvega/spring-boot-intro/tree/master/guides/sending-email-async