How could I send an email with Spring 4 (and Spring Boot) by using a pure annotation-based approach (according to the Java Configurations rules)?
相关问题
- java.lang.IllegalArgumentException: Cannot set to
- Spring Data MongoDB - lazy access to some fields
- Declaring an explict object dependency in Spring
- Decoding body parameters with Spring
- Spring Integration - Inbound file endpoint. How to
相关文章
- java JDK动态代理和cglib动态代理最后获取的代理对象都为null的问题
- org.xml.sax.SAXParseException; lineNumber: 7; colu
- SpringMVC如何把File封装到Map中?
- Spring: controller inheritance using @Controller a
- How to load @Configuration classes from separate J
- Java spring framework - how to set content type?
- Java/Spring MVC: provide request context to child
- Spring 5 Web Reactive - Hot Publishing - How to us
In
pom.xml
:In
application.properties
:In
Foo.java
:Personally, I recommend running a localhost MTA, and using it to relay to your real MTA (like Gmail or SES, or your own). This gives you a "free" asynchronous queue, and centralizes config. I like OpenSMTP.
In addition to geoand's answer: if you don't want to hard code the mail properties or to write XML, you can add your properties to a file (mail.properties for example) in your resources, and add this kind of code in the MailConfig class:
And the range of properties you can use is all defined on these pages
https://javamail.java.net/nonav/docs/api/
https://javamail.java.net/nonav/docs/api/com/sun/mail/smtp/package-summary.html
But you'll still have to set Host, Port, Username and Password from the JavaMailSenderImpl's methods as it wont directly use the ones set in your properties.
Using Spring Boot 1.2 onwards, a JavaMailSender could be auto-configured for you. I've got this video explaining how exactly to send mails using Spring Boot 1.2 onwards. Spring Lemon's source code could be referred to for the exact details.
A simple solution (where you will be using an SMTP server with no authentication) for configuring the email service would by
Spring must be able to resolve the properties
email.host
andemail.port
in of the usual ways (in case of Spring Boot the simplest is to put then in application.properties)In any class that needs the services of JavaMailSender, just inject with one of the usual ways (such as
@Autowired private JavaMailSender javaMailSender
)UPDATE
Note that since version 1.2.0.RC1 Spring Boot can auto-configure
JavaMailSender
for you. Check out this part of the documentation. As you can see from the documentation, almost no configuration is required to get up and running!With Spring-Boot it was close to trivial, with one adjustment needed for smtp.office365.com mail server - which is what this company is using.
Before making this adjustment the authentication to the Office365 SMTP server kept failing and we'd get an error along the lines of:
This was even though we were setting a username and password that were being correctly picked up by Spring's MailProperties class.
Turns out Office365 needs TLS authentication enabled and Spring's current JavaMail implementation doesn't have a simple way to do that with properties. The solution is to create our own javax.mail.Session instance and register it with Spring.
The whole picture follows.
In the pom.xml file, add:
Where spring-boot.version is defined elsewhere (in a parent pom in this case) and in this case has a value of 1.3.1.RELEASE
Make sure to include the package and/or the auto-configuration class if you itemize those in your main application - if you use the default @SpringBootApplication this isn't needed, but in my case I added MailSenderAutoConfiguration.class to the @Import annotation's list of classes.
I created a simple EmailSender class:
Where the @Slf4j is a lombok annotation, and the @Subscribe is for Guava's EventBus, which is how this app lets the EmailSender know there's a message to send. I use a trivial EmailMessageEvent POJO that has a subject and message text - good enough for this app's purposes.
The MessageConfig class just makes it easy to set up message defaults along with the rest of the application's configuration, and it has the one piece of special sauce that was needed to make this work with an Office365 SMTP server, a custom javax.mail.Session instance registered as a Spring Bean:
The @Data is again a Lombok annotation - automatagically adds mutator and accessor methods, toString(), equals() & hashCode(), etc.
The limitation of Spring's JavaMailSender (JavaMailSenderImpl) is that its Session is not directly configurable, in particular there's no way to enable TLS authentication via a property. However, if there's a javax.mail.Session Bean registered in the context, that will be injected (conditionally autowired) into the MailSenderAutoConfiguration and then used to construct the JavaMailSenderImpl instance.
So we register just such a Bean via the getSession() method. For good measure we make the Session we construct here the default one for the JVM - change it to call getInstance() if you don't want that behavior.
After adding this Session @Bean everything worked.