Reputation: 107
I know I can use the following properties to automatically create a JavaMailSender
bean:
spring.mail.host=hostname
spring.mail.port=587
spring.mail.username=username
spring.mail.password=password
However, how can I define these properties to create two JavaMailSender
beans so I can send emails from different SMTP servers?
I tried defining the following properties:
# Properties for sender 1
spring.mail.host=hostname
spring.mail.port=587
spring.mail.username=username
spring.mail.password=password
# Properties for sender 2
spring.mail.host1=hostname2
spring.mail.port1=587
spring.mail.username1=username2
spring.mail.password1=password2
However, this does not work as I expected, so how can I create two JavaMailSender
beans using Spring boot?
Upvotes: 6
Views: 8373
Reputation: 1
For a correct injection of the javaMailProperties it is necessary to read the keys manually by means of the relative prefix.
@Configuration
public class EmailConfig {
public static final String MAIL_SENDER_PRIMARY_KEY = "spring.mail.primary";
public static final String MAIL_SENDER_PRIMARY_PROPERTIES_KEY = "spring.mail.primary.properties";
public static final String MAIL_SENDER_SECONDARY_KEY = "spring.mail.secondary";
public static final String MAIL_SENDER_SECONDARY_PROPERTIES_KEY = "spring.mail.secondary.properties";
public static final String KEY_SEPARATOR = ".";
public static final String EMPTY_STRING = "";
@Autowired
Environment env;
@Bean
@ConfigurationProperties(prefix = MAIL_SENDER_PRIMARY_KEY)
public JavaMailSender primarySender() {
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
return javaMailSenderWithProperties(javaMailSender,MAIL_SENDER_PRIMARY_PROPERTIES_KEY);
}
@Bean
@ConfigurationProperties(prefix = MAIL_SENDER_SECONDARY_KEY)
public JavaMailSender secondarySender() {
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
return javaMailSenderWithProperties(javaMailSender,MAIL_SENDER_SECONDARY_PROPERTIES_KEY);
}
private JavaMailSender javaMailSenderWithProperties(JavaMailSenderImpl javaMailSender, String prefix) {
Properties props = new Properties();
if (env instanceof ConfigurableEnvironment) {
for (PropertySource<?> propertySource : ((ConfigurableEnvironment) env).getPropertySources()) {
if (propertySource instanceof EnumerablePropertySource) {
for (String key : ((EnumerablePropertySource) propertySource).getPropertyNames()) {
if (key.startsWith(prefix)) {
props.setProperty(key.replaceAll(prefix + KEY_SEPARATOR, EMPTY_STRING), propertySource.getProperty(key).toString());
}
}
}
}
}
javaMailSender.setJavaMailProperties(props);
return javaMailSender;
}
}
spring.mail.primary.username=
spring.mail.primary.password=
spring.mail.primary.host=
spring.mail.primary.port=
spring.mail.primary.protocol=smtp
spring.mail.primary.properties.mail.smtp.auth=true
spring.mail.primary.properties.mail.smtp.connectiontimeout=5000
spring.mail.primary.properties.mail.smtp.timeout=5000
spring.mail.primary.properties.mail.smtp.writetimeout=5000
spring.mail.primary.properties.mail.smtp.socketFactory.class=
spring.mail.primary.properties.mail.smtp.socketFactory.port=
#spring.mail.primary.properties.mail.smtp.auth=true
spring.mail.primary.properties.mail.smtp.starttls.enable=true
spring.mail.primary.properties.mail.smtp.starttls.required=true
spring.mail.secondary.host=
spring.mail.secondary.port=
spring.mail.secondary.username=
spring.mail.secondary.password=
spring.mail.secondary.protocol=
spring.mail.secondary.properties.mail.smtp.auth=true
spring.mail.secondary.properties.mail.smtp.connectiontimeout=5000
spring.mail.secondary.properties.mail.smtp.timeout=5000
spring.mail.secondary.properties.mail.smtp.writetimeout=5000
spring.mail.secondary.properties.mail.smtp.socketFactory.class=
spring.mail.secondary.properties.mail.smtp.socketFactory.port=
#spring.mail.secondary.properties.mail.smtp.auth=true
spring.mail.secondary.properties.mail.smtp.starttls.enable=true
spring.mail.secondary.properties.mail.smtp.starttls.required=true
@Service
public class EmailService {
private JavaMailSender primarySender;
private JavaMailSender secondarySender;
public EmailService (
@Qualifier("primarySender") JavaMailSender primarySender,
@Qualifier("secondarySender") JavaMailSender secondarySender) {
this.primarySender = primarySender;
this.secondarySender = secondarySender;
}
public void sendPrimaryEmail(String from, String to, String subject, String text){
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(from);
message.setTo(to);
message.setSubject(subject);
message.setText(text);
primarySender.send(message);
}
public void sendSecondaryEmail(String from, String to, String subject, String text)
{
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(from);
message.setTo(to);
message.setSubject(subject);
message.setText(text);
secondarySender.send(message);
}
}
Upvotes: 0
Reputation: 41
If you are using the mail properties, at least in my case, the mail properties were not read with the @ConfigurationProperties. So I change the solution a bit:
@Bean
@ConfigurationProperties(prefix = "spring.mail.primarySender")
public JavaMailSender primarySender() {
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
return javaMailSenderWithProperties(javaMailSender);
}
@Bean
@ConfigurationProperties(prefix = "spring.mail.secondarySender")
public JavaMailSender secondarySender() {
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
return javaMailSenderWithProperties(javaMailSender);
}
private JavaMailSender javaMailSenderWithProperties(JavaMailSenderImpl javaMailSender) {
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
javaMailSender.setJavaMailProperties(props);
return javaMailSender;
}
Upvotes: 4
Reputation: 44725
Spring boot will only initialize one JavaMailSender
as soon as it finds the spring.mail.*
properties. If you need multiple ones, you have to define these beans by yourself. If you only need the properties host, port, username and password, you could use this simple configuration:
@Configuration
public class MailConfiguration {
@Bean
@ConfigurationProperties(prefix = "spring.mail.primary")
public JavaMailSender primarySender() {
return new JavaMailSenderImpl();
}
@Bean
@ConfigurationProperties(prefix = "spring.mail.secondary")
public JavaMailSender secondarySender() {
return new JavaMailSenderImpl();
}
}
However, this will not work if you also want to configure spring.mail.properties.*
as well. In order to do that, your configuration will be a bit more complex, since you'll have to do the following:
MailProperties
using the same @ConfigurationProperties
as you can see above.MailProperties
in a similar way as Spring boot does within MailSenderPropertiesConfiguration
.After that, you can use the spring.mail.primary.*
properties and spring.mail.secondary.*
properties as you're used to. For example:
spring.mail.primary.host=host1
spring.mail.primary.port=port1
spring.mail.primary.username=username1
spring.mail.primary.password=password1
spring.mail.secondary.host=host2
spring.mail.secondary.port=port2
spring.mail.secondary.username=username2
spring.mail.secondary.password=password2
After that, you can autowire both primarySender
and secondarySender
. Make sure to use the @Qualifier
annotation to tell Spring which is which:
@Service
public class MailService {
private JavaMailSender primarySender;
private JavaMailSender secondarySender;
public MailService(
@Qualifier("primarySender") JavaMailSender primarySender,
@Qualifier("secondarySender") JavaMailSender secondarySender) {
this.primarySender = primarySender;
this.secondarySender = secondarySender;
}
}
Upvotes: 21