diff --git a/notify-spring-boot-starter/src/main/java/com/hxuanyu/notify/config/MailProperties.java b/notify-spring-boot-starter/src/main/java/com/hxuanyu/notify/config/MailProperties.java new file mode 100644 index 0000000..0daa6a4 --- /dev/null +++ b/notify-spring-boot-starter/src/main/java/com/hxuanyu/notify/config/MailProperties.java @@ -0,0 +1,92 @@ +package com.hxuanyu.notify.config; + +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * @author hxuanyu + */ +@ConfigurationProperties(prefix = "notify.mail") +public class MailProperties { + private static final Charset DEFAULT_CHARSET; + private String host; + private Integer port; + private String username; + private String password; + private String protocol = "smtp"; + private Charset defaultEncoding; + private Map<String, String> properties; + private String jndiName; + + public MailProperties() { + this.defaultEncoding = DEFAULT_CHARSET; + this.properties = new HashMap(); + } + + public String getHost() { + return this.host; + } + + public void setHost(String host) { + this.host = host; + } + + public Integer getPort() { + return this.port; + } + + public void setPort(Integer port) { + this.port = port; + } + + public String getUsername() { + return this.username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return this.password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getProtocol() { + return this.protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + public Charset getDefaultEncoding() { + return this.defaultEncoding; + } + + public void setDefaultEncoding(Charset defaultEncoding) { + this.defaultEncoding = defaultEncoding; + } + + public Map<String, String> getProperties() { + return this.properties; + } + + public void setJndiName(String jndiName) { + this.jndiName = jndiName; + } + + public String getJndiName() { + return this.jndiName; + } + + static { + DEFAULT_CHARSET = StandardCharsets.UTF_8; + } +} diff --git a/notify-spring-boot-starter/src/main/java/com/hxuanyu/notify/config/NotifyConfiguration.java b/notify-spring-boot-starter/src/main/java/com/hxuanyu/notify/config/NotifyConfiguration.java index 02f8d1c..5ca360a 100644 --- a/notify-spring-boot-starter/src/main/java/com/hxuanyu/notify/config/NotifyConfiguration.java +++ b/notify-spring-boot-starter/src/main/java/com/hxuanyu/notify/config/NotifyConfiguration.java @@ -1,19 +1,57 @@ package com.hxuanyu.notify.config; import com.google.common.util.concurrent.ThreadFactoryBuilder; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.ImportResource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.*; +import org.springframework.mail.javamail.JavaMailSenderImpl; +import java.util.Map; +import java.util.Properties; import java.util.concurrent.*; /** * @author hxuanyu */ @Configuration -@ComponentScan("com.hxuanyu.notify.service") +@ComponentScan("com.hxuanyu.notify") +@EnableConfigurationProperties(MailProperties.class) public class NotifyConfiguration { + @Autowired + MailProperties mailProperties; + + @Bean + JavaMailSenderImpl mailSender(MailProperties properties) { + JavaMailSenderImpl sender = new JavaMailSenderImpl(); + this.applyProperties(properties, sender); + return sender; + } + + private void applyProperties(MailProperties properties, JavaMailSenderImpl sender) { + sender.setHost(properties.getHost()); + if (properties.getPort() != null) { + sender.setPort(properties.getPort()); + } + + sender.setUsername(properties.getUsername()); + sender.setPassword(properties.getPassword()); + sender.setProtocol(properties.getProtocol()); + if (properties.getDefaultEncoding() != null) { + sender.setDefaultEncoding(properties.getDefaultEncoding().name()); + } + + if (!properties.getProperties().isEmpty()) { + sender.setJavaMailProperties(this.asProperties(properties.getProperties())); + } + + } + + private Properties asProperties(Map<String, String> source) { + Properties properties = new Properties(); + properties.putAll(source); + return properties; + } + @Bean(name = "mailExecutorService") public ExecutorService mailExecutorService() { // 使用 ThreadFactoryBuilder 创建自定义线程名称的 ThreadFactory diff --git a/notify-spring-boot-starter/src/main/java/com/hxuanyu/notify/service/impl/MailServiceImpl.java b/notify-spring-boot-starter/src/main/java/com/hxuanyu/notify/service/impl/MailServiceImpl.java index 0c93051..bbe4e5f 100644 --- a/notify-spring-boot-starter/src/main/java/com/hxuanyu/notify/service/impl/MailServiceImpl.java +++ b/notify-spring-boot-starter/src/main/java/com/hxuanyu/notify/service/impl/MailServiceImpl.java @@ -2,18 +2,19 @@ package com.hxuanyu.notify.service.impl; import com.hxuanyu.notify.common.MailQueue; +import com.hxuanyu.notify.config.MailProperties; import com.hxuanyu.notify.model.Mail; import com.hxuanyu.notify.service.MailService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.JavaMailSenderImpl; import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.stereotype.Service; -import org.thymeleaf.TemplateEngine; -import org.thymeleaf.context.Context; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; @@ -27,16 +28,15 @@ import java.util.concurrent.ExecutorService; */ @Service public class MailServiceImpl implements MailService { + @Resource + MailProperties mailProperties; private static final Logger logger = LoggerFactory.getLogger(MailServiceImpl.class); private static boolean isRunning = true; ExecutorService executor; - private static JavaMailSender javaMailSender; - private static TemplateEngine templateEngine; + private JavaMailSender javaMailSender; - private static String defaultFrom; - @@ -45,7 +45,7 @@ public class MailServiceImpl implements MailService { executor.submit(new PollMail()); } - static class PollMail implements Runnable { + class PollMail implements Runnable { @Override public void run() { while (isRunning) { @@ -71,10 +71,10 @@ public class MailServiceImpl implements MailService { } - private static void sendMailSync(Mail mail) { + private void sendMailSync(Mail mail) { String from = mail.getFrom(); if (from == null) { - from = defaultFrom; + from = mailProperties.getUsername(); logger.info("未传入发件人,从配置中读取:{}", from); } MimeMessage mimeMessage; @@ -87,12 +87,7 @@ public class MailServiceImpl implements MailService { mimeMessageHelper.setFrom(from); mimeMessageHelper.setTo(mail.getTo()); mimeMessageHelper.setSubject(mail.getSubject()); - // 利用 Thymeleaf 引擎渲染 HTML - Context context = new Context(); - // 设置注入的变量 - context.setVariable("templates/mail", mail); - // 模板设置为 "mail" - String content = templateEngine.process("templates/mail/mail", context); + String content = mail.getContent(); // 设置邮件内容 // true 表示开启 html mimeMessageHelper.setText(content, true); @@ -112,9 +107,9 @@ public class MailServiceImpl implements MailService { } - @Resource + @Autowired public void setJavaMailSender(JavaMailSender javaMailSender) { - MailServiceImpl.javaMailSender = javaMailSender; + this.javaMailSender = javaMailSender; } @Autowired @@ -122,14 +117,4 @@ public class MailServiceImpl implements MailService { this.executor = executor; } - - @Autowired - public void setTemplateEngine(TemplateEngine templateEngine) { - MailServiceImpl.templateEngine = templateEngine; - } - - @Value("${spring.mail.username}") - public void setDefaultFrom(String defaultFrom) { - MailServiceImpl.defaultFrom = defaultFrom; - } } \ No newline at end of file diff --git a/notify-spring-boot-starter/src/main/java/com/hxuanyu/notify/service/impl/NotifyServiceImpl.java b/notify-spring-boot-starter/src/main/java/com/hxuanyu/notify/service/impl/NotifyServiceImpl.java index f2f952b..e9b31f7 100644 --- a/notify-spring-boot-starter/src/main/java/com/hxuanyu/notify/service/impl/NotifyServiceImpl.java +++ b/notify-spring-boot-starter/src/main/java/com/hxuanyu/notify/service/impl/NotifyServiceImpl.java @@ -6,6 +6,7 @@ import com.hxuanyu.notify.service.MailService; import com.hxuanyu.notify.service.NotifyService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.stereotype.Service; import javax.annotation.Resource; diff --git a/notify-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/notify-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 0000000..bee3a2c --- /dev/null +++ b/notify-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,43 @@ +{ + "properties": [ + { + "name": "notify.mail.host", + "type": "java.lang.String", + "description": "Description for notify.mail.host." + }, + { + "name": "notify.mail.protocol", + "type": "java.lang.String", + "description": "Description for notify.mail.protocol." + }, + { + "name": "notify.mail.default-encoding", + "type": "java.lang.String", + "description": "Description for notify.mail.default-encoding." + }, + { + "name": "notify.mail.password", + "type": "java.lang.String", + "description": "Description for notify.mail.password." + }, + { + "name": "notify.mail.username", + "type": "java.lang.String", + "description": "Description for notify.mail.username." + }, + { + "name": "notify.mail.port", + "type": "java.lang.String", + "description": "Description for notify.mail.port." + }, + { + "name": "notify.mail.properties.mail.debug", + "type": "java.lang.String", + "description": "Description for notify.mail.properties.mail.debug." + }, + { + "name": "notify.mail.properties.stmp.socketFactory.class", + "type": "java.lang.String", + "description": "Description for notify.mail.properties.stmp.socketFactory.class." + } + ] } \ No newline at end of file diff --git a/notify-spring-boot-starter/src/main/resources/templates/mail/mail.html b/notify-spring-boot-starter/src/main/resources/templates/mail/mail.html deleted file mode 100644 index 0cb7677..0000000 --- a/notify-spring-boot-starter/src/main/resources/templates/mail/mail.html +++ /dev/null @@ -1,129 +0,0 @@ -<!DOCTYPE html> -<html lang="zh" xmlns:th="http://www.thymeleaf.org"> -<!--${government}--> -<!--${title}--> -<!--${suggestion}--> -<!--${deadline}--> -<!--${secret}--> -<!--${url}--> -<!--${officeName}--> -<!--${createTime}--> -<head> - <meta charset="utf-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no"> - <title>${title}</title> - <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.min.css"> - <style> - .contact-clean { - background: #f1f7fc; - padding: 80px 0; - } - - a { - text-decoration: none; - } - - @media (max-width: 767px) { - .contact-clean { - padding: 20px 0; - } - } - - .contact-clean form { - max-width: 480px; - width: 90%; - margin: 0 auto; - background-color: #ffffff; - padding: 40px; - border-radius: 4px; - color: #505e6c; - box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.1); - } - - @media (max-width: 767px) { - .contact-clean form { - padding: 30px; - } - } - - .contact-clean h2 { - margin-top: 5px; - font-weight: bold; - font-size: 28px; - margin-bottom: 36px; - color: inherit; - } - - .contact-clean .form-group:last-child { - margin-bottom: 5px; - } - - .contact-clean form .form-control { - background: #fff; - border-radius: 2px; - box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.05); - outline: none; - color: inherit; - padding-left: 12px; - height: 42px; - } - - .contact-clean form .form-control:focus { - border: 1px solid #b2b2b2; - } - - .contact-clean form textarea.form-control { - min-height: 100px; - max-height: 260px; - padding-top: 10px; - resize: vertical; - } - - .contact-clean form .btn { - padding: 16px 32px; - border: none; - background: none; - box-shadow: none; - text-shadow: none; - opacity: 0.9; - text-transform: uppercase; - font-weight: bold; - font-size: 13px; - letter-spacing: 0.4px; - line-height: 1; - outline: none !important; - } - - .contact-clean form .btn:hover { - opacity: 1; - } - - .contact-clean form .btn:active { - transform: translateY(1px); - } - - .contact-clean form .btn-primary { - background-color: #055ada !important; - margin-top: 15px; - color: #fff; - } - </style> -</head> - -<body> -<div class="contact-clean"> - <form method="post"> - <h2 class="text-center" th:text="${mail.getSubject()}"></h2> - <p th:utext="${mail.getContent()}"></p> - <div class="alert alert-danger" role="alert"> - <span> - <strong>注意</strong>本邮件由系统自动发送,请勿回复本邮件,如果邮件内容您并不知情,请忽略本邮件 - </span> - </div> - </form> -</div> -<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> -<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/js/bootstrap.bundle.min.js"></script> -</body> - -</html> \ No newline at end of file diff --git a/notify-spring-boot-starter/src/main/resources/config/application.yml b/test/src/main/resources/application.yml similarity index 52% rename from notify-spring-boot-starter/src/main/resources/config/application.yml rename to test/src/main/resources/application.yml index 39e166d..ee42b23 100644 --- a/notify-spring-boot-starter/src/main/resources/config/application.yml +++ b/test/src/main/resources/application.yml @@ -1,10 +1,10 @@ -spring: +notify: mail: - host: smtp.domain + host: smtp.qq.com protocol: smtp default-encoding: UTF-8 - password: your_password - username: your_username + password: bjmtskwfjrvqdhgb + username: 2202043370@qq.com port: 587 properties: mail: diff --git a/test/src/main/resources/templates/mail/mail.html b/test/src/main/resources/templates/mail/mail.html deleted file mode 100644 index 0cb7677..0000000 --- a/test/src/main/resources/templates/mail/mail.html +++ /dev/null @@ -1,129 +0,0 @@ -<!DOCTYPE html> -<html lang="zh" xmlns:th="http://www.thymeleaf.org"> -<!--${government}--> -<!--${title}--> -<!--${suggestion}--> -<!--${deadline}--> -<!--${secret}--> -<!--${url}--> -<!--${officeName}--> -<!--${createTime}--> -<head> - <meta charset="utf-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no"> - <title>${title}</title> - <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.min.css"> - <style> - .contact-clean { - background: #f1f7fc; - padding: 80px 0; - } - - a { - text-decoration: none; - } - - @media (max-width: 767px) { - .contact-clean { - padding: 20px 0; - } - } - - .contact-clean form { - max-width: 480px; - width: 90%; - margin: 0 auto; - background-color: #ffffff; - padding: 40px; - border-radius: 4px; - color: #505e6c; - box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.1); - } - - @media (max-width: 767px) { - .contact-clean form { - padding: 30px; - } - } - - .contact-clean h2 { - margin-top: 5px; - font-weight: bold; - font-size: 28px; - margin-bottom: 36px; - color: inherit; - } - - .contact-clean .form-group:last-child { - margin-bottom: 5px; - } - - .contact-clean form .form-control { - background: #fff; - border-radius: 2px; - box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.05); - outline: none; - color: inherit; - padding-left: 12px; - height: 42px; - } - - .contact-clean form .form-control:focus { - border: 1px solid #b2b2b2; - } - - .contact-clean form textarea.form-control { - min-height: 100px; - max-height: 260px; - padding-top: 10px; - resize: vertical; - } - - .contact-clean form .btn { - padding: 16px 32px; - border: none; - background: none; - box-shadow: none; - text-shadow: none; - opacity: 0.9; - text-transform: uppercase; - font-weight: bold; - font-size: 13px; - letter-spacing: 0.4px; - line-height: 1; - outline: none !important; - } - - .contact-clean form .btn:hover { - opacity: 1; - } - - .contact-clean form .btn:active { - transform: translateY(1px); - } - - .contact-clean form .btn-primary { - background-color: #055ada !important; - margin-top: 15px; - color: #fff; - } - </style> -</head> - -<body> -<div class="contact-clean"> - <form method="post"> - <h2 class="text-center" th:text="${mail.getSubject()}"></h2> - <p th:utext="${mail.getContent()}"></p> - <div class="alert alert-danger" role="alert"> - <span> - <strong>注意</strong>本邮件由系统自动发送,请勿回复本邮件,如果邮件内容您并不知情,请忽略本邮件 - </span> - </div> - </form> -</div> -<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> -<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/js/bootstrap.bundle.min.js"></script> -</body> - -</html> \ No newline at end of file