diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailProperties.java index b8db99c6c7e..a1f9250bdd2 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailProperties.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * Copyright 2012-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -66,12 +66,12 @@ public class MailProperties { private Charset defaultEncoding = DEFAULT_CHARSET; /** - * Additional JavaMail session properties. + * Additional JavaMail Session properties. */ private Map properties = new HashMap(); /** - * Session JNDI name. When set, takes precedence to others mail settings. + * Session JNDI name. When set, takes precedence to others Session settings. */ private String jndiName; diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailSenderAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailSenderAutoConfiguration.java index 3bc70bf53fe..aca28f72e23 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailSenderAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailSenderAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * Copyright 2012-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,14 +16,9 @@ package org.springframework.boot.autoconfigure.mail; -import java.util.Map; -import java.util.Properties; - import javax.activation.MimeType; -import javax.mail.Session; import javax.mail.internet.MimeMessage; -import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; @@ -31,12 +26,10 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration.MailSenderCondition; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.mail.MailSender; -import org.springframework.mail.javamail.JavaMailSenderImpl; /** * {@link EnableAutoConfiguration Auto configuration} for email support. @@ -47,60 +40,16 @@ import org.springframework.mail.javamail.JavaMailSenderImpl; * @since 1.2.0 */ @Configuration -@ConditionalOnClass({ MimeMessage.class, MimeType.class }) +@ConditionalOnClass({ MimeMessage.class, MimeType.class, MailSender.class }) @ConditionalOnMissingBean(MailSender.class) @Conditional(MailSenderCondition.class) @EnableConfigurationProperties(MailProperties.class) -@Import(JndiSessionConfiguration.class) +@Import({ MailSenderJndiConfiguration.class, MailSenderPropertiesConfiguration.class }) public class MailSenderAutoConfiguration { - private final MailProperties properties; - - private final Session session; - - public MailSenderAutoConfiguration(MailProperties properties, - ObjectProvider session) { - this.properties = properties; - this.session = session.getIfAvailable(); - } - - @Bean - public JavaMailSenderImpl mailSender() { - JavaMailSenderImpl sender = new JavaMailSenderImpl(); - if (this.session != null) { - sender.setSession(this.session); - } - else { - applyProperties(sender); - } - return sender; - } - - private void applyProperties(JavaMailSenderImpl sender) { - sender.setHost(this.properties.getHost()); - if (this.properties.getPort() != null) { - sender.setPort(this.properties.getPort()); - } - sender.setUsername(this.properties.getUsername()); - sender.setPassword(this.properties.getPassword()); - sender.setProtocol(this.properties.getProtocol()); - if (this.properties.getDefaultEncoding() != null) { - sender.setDefaultEncoding(this.properties.getDefaultEncoding().name()); - } - if (!this.properties.getProperties().isEmpty()) { - sender.setJavaMailProperties(asProperties(this.properties.getProperties())); - } - } - - private Properties asProperties(Map source) { - Properties properties = new Properties(); - properties.putAll(source); - return properties; - } - /** - * Condition to trigger the creation of a {@link JavaMailSenderImpl}. This kicks in if - * either the host or jndi name property is set. + * Condition to trigger the creation of a {@link MailSender}. This kicks in if either + * the host or jndi name property is set. */ static class MailSenderCondition extends AnyNestedCondition { diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/JndiSessionConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailSenderJndiConfiguration.java similarity index 75% rename from spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/JndiSessionConfiguration.java rename to spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailSenderJndiConfiguration.java index 366f01c2539..0c9c8cacb2c 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/JndiSessionConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailSenderJndiConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * Copyright 2012-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,9 +26,11 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jndi.JndiLocatorDelegate; +import org.springframework.mail.MailSender; +import org.springframework.mail.javamail.JavaMailSenderImpl; /** - * Auto-configure a {@link Session} available on JNDI. + * Auto-configure a {@link MailSender} based on a {@link Session} available on JNDI. * * @author Eddú Meléndez * @author Stephane Nicoll @@ -37,14 +39,22 @@ import org.springframework.jndi.JndiLocatorDelegate; @ConditionalOnClass(Session.class) @ConditionalOnProperty(prefix = "spring.mail", name = "jndi-name") @ConditionalOnJndi -class JndiSessionConfiguration { +class MailSenderJndiConfiguration { private final MailProperties properties; - JndiSessionConfiguration(MailProperties properties) { + MailSenderJndiConfiguration(MailProperties properties) { this.properties = properties; } + @Bean + public JavaMailSenderImpl mailSender(Session session) { + JavaMailSenderImpl sender = new JavaMailSenderImpl(); + sender.setDefaultEncoding(this.properties.getDefaultEncoding().name()); + sender.setSession(session); + return sender; + } + @Bean @ConditionalOnMissingBean public Session session() { diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailSenderPropertiesConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailSenderPropertiesConfiguration.java new file mode 100644 index 00000000000..ee02bde721f --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailSenderPropertiesConfiguration.java @@ -0,0 +1,76 @@ +/* + * Copyright 2012-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.mail; + +import java.util.Map; +import java.util.Properties; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.mail.MailSender; +import org.springframework.mail.javamail.JavaMailSenderImpl; + +/** + * Auto-configure a {@link MailSender} based on properties configuration. + * + * @author Oliver Gierke + * @author Eddú Meléndez + * @author Stephane Nicoll + */ +@Configuration +@ConditionalOnProperty(prefix = "spring.mail", name = "host") +class MailSenderPropertiesConfiguration { + + private final MailProperties properties; + + MailSenderPropertiesConfiguration(MailProperties properties) { + this.properties = properties; + } + + @Bean + @ConditionalOnMissingBean + public JavaMailSenderImpl mailSender() { + JavaMailSenderImpl sender = new JavaMailSenderImpl(); + applyProperties(sender); + return sender; + } + + private void applyProperties(JavaMailSenderImpl sender) { + sender.setHost(this.properties.getHost()); + if (this.properties.getPort() != null) { + sender.setPort(this.properties.getPort()); + } + sender.setUsername(this.properties.getUsername()); + sender.setPassword(this.properties.getPassword()); + sender.setProtocol(this.properties.getProtocol()); + if (this.properties.getDefaultEncoding() != null) { + sender.setDefaultEncoding(this.properties.getDefaultEncoding().name()); + } + if (!this.properties.getProperties().isEmpty()) { + sender.setJavaMailProperties(asProperties(this.properties.getProperties())); + } + } + + private Properties asProperties(Map source) { + Properties properties = new Properties(); + properties.putAll(source); + return properties; + } + +} diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mail/MailSenderAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mail/MailSenderAutoConfigurationTests.java index c79a09cd874..7715a0081a2 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mail/MailSenderAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mail/MailSenderAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * Copyright 2012-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -178,6 +178,36 @@ public class MailSenderAutoConfigurationTests { load(EmptyConfig.class, "spring.mail.jndi-name:foo"); } + @Test + public void jndiSessionTakesPrecedenceOverProperties() throws NamingException { + Session session = configureJndiSession("foo"); + load(EmptyConfig.class, "spring.mail.jndi-name:foo", + "spring.mail.host:localhost"); + Session sessionBean = this.context.getBean(Session.class); + assertThat(sessionBean).isEqualTo(session); + assertThat(this.context.getBean(JavaMailSenderImpl.class).getSession()) + .isEqualTo(sessionBean); + } + + @Test + public void defaultEncodingWithProperties() { + load(EmptyConfig.class, "spring.mail.host:localhost", + "spring.mail.default-encoding:UTF-16"); + JavaMailSenderImpl bean = (JavaMailSenderImpl) this.context + .getBean(JavaMailSender.class); + assertThat(bean.getDefaultEncoding()).isEqualTo("UTF-16"); + } + + @Test + public void defaultEncodingWithJndi() throws NamingException { + configureJndiSession("foo"); + load(EmptyConfig.class, "spring.mail.jndi-name:foo", + "spring.mail.default-encoding:UTF-16"); + JavaMailSenderImpl bean = (JavaMailSenderImpl) this.context + .getBean(JavaMailSender.class); + assertThat(bean.getDefaultEncoding()).isEqualTo("UTF-16"); + } + @Test public void connectionOnStartup() throws MessagingException { load(MockMailConfiguration.class, "spring.mail.host:10.0.0.23", diff --git a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc index e6976e8ae61..e507c9a026b 100644 --- a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc +++ b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc @@ -96,10 +96,10 @@ content into your application; rather pick only the properties that you need. # Email ({sc-spring-boot-autoconfigure}/mail/MailProperties.{sc-ext}[MailProperties]) spring.mail.default-encoding=UTF-8 # Default MimeMessage encoding. spring.mail.host= # SMTP server host. For instance `smtp.example.com` - spring.mail.jndi-name= # Session JNDI name. When set, takes precedence to others mail settings. + spring.mail.jndi-name= # Session JNDI name. When set, takes precedence to others Session settings. spring.mail.password= # Login password of the SMTP server. spring.mail.port= # SMTP server port. - spring.mail.properties.*= # Additional JavaMail session properties. + spring.mail.properties.*= # Additional JavaMail Session properties. spring.mail.protocol=smtp # Protocol used by the SMTP server. spring.mail.test-connection=false # Test that the mail server is available on startup. spring.mail.username= # Login user of the SMTP server. diff --git a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc index 7c4dc0ef4e8..4c589334c03 100644 --- a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc +++ b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc @@ -5046,6 +5046,15 @@ to avoid having a thread blocked by an unresponsive mail server: spring.mail.properties.mail.smtp.writetimeout=5000 ---- +It is also possible to configure a `JavaMailSender` with an existing `Session` from JNDI: + +[source,properties,indent=0] +---- + spring.mail.jndi-name=mail/Session +---- + +When a `jndi-name` is set, it takes precedence over all other Session-related settings. + [[boot-features-jta]]