Search code examples
springspring-bootspring-cloudamazon-ses

Is it possible to have two implementations of MailSender in the Spring Boot app?


I have a Spring Boot app that has an email sending part. I'd like to use SMTP org.springframework.mail.javamailJavaMailSenderImpl with my "dev" profile, and the AWS SES implementation io.awspring.cloud.ses.SimpleEmailServiceMailSender with my "prod" profile. Both implement org.springframework.mail.MailSender. What's the "proper" way to make it work?


Solution

  • The proper solution in my opinion is to use the properties to switch between the MailSender implementation.

    To do that, you need to know on which condition each mail sender is created. That is defined in the corresponding AutoConfiguration classes for Spring Boot.

    The JavaMailSenderImpl Bean is only created if the spring.mail.host or spring.mail.jndi-name property is set. See: Source

    The SimpleEmailServiceJavaMailSender Bean is only created if the spring.cloud.aws.ses.enabled is true or is not set at all (you have to set it explicitly to false, otherwise it will always be used). See: Source

    That means you have to configure it this way:

    in the dev properties (only JavaMailSenderImpl):

    spring.mail.host=... # must be set
    spring.cloud.aws.ses.enabled=false # must be false
    

    in the prod properties (only SimpleEmailServiceJavaMailSender):

    # Do not set spring.mail.host at all
    spring.cloud.aws.ses.enabled=true # can be true or omitted
    

    To use them, you just have to inject the MailSender or JavaMailSender interface and it will use the implementation based on the properties