ข้อผิดพลาด autowire JavaMailSenderImpl หาก spring.mail.host ไม่ได้อยู่ใน application.properties

ฉันมี "ปัญหา" เล็กน้อยในการใช้ JavaMailSenderImpl เพื่อส่งอีเมลในแอปพลิเคชัน Spring Boot ของฉัน

ฉันกำลังพยายามตั้งค่าคุณสมบัติทั้งหมดแบบไดนามิก (ฉันจะต้องการให้อ่านจากฐานข้อมูลในอนาคต) แต่ด้วยเหตุผลที่ฉันไม่ทราบ การเดินสายอัตโนมัติ JavaMailSenderImpl จะใช้งานได้ก็ต่อเมื่อมี "spring.mail.host" อยู่ใน application.properties ของฉัน .

มันไม่สำคัญว่าค่าที่ฉันตั้งไว้จะเป็นอย่างไร (สามารถว่างเปล่าได้ มันไม่สำคัญเพราะฉันตั้งค่าที่ถูกต้องในภายหลัง) แต่คุณสมบัติจะต้องอยู่ที่นั่น ไม่เช่นนั้นการเดินสายอัตโนมัติจะล้มเหลว

นี่คือตัวควบคุมของฉัน:

import java.util.Properties;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.MailException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;


@Controller
public class MailController {

    @Autowired
    private JavaMailSenderImpl ms;


    @RequestMapping("/mail")
    public String send(Model model){

        SimpleMailMessage message;
        String fromEmail="[email protected]";
        String toEmail ="xxxxxxx";

        Properties mailProperties = new Properties();
        mailProperties.put("mail.smtp.starttls.enable", true);
        mailProperties.put("mail.smtp.ssl.trust", "smtp.gmail.com");

        ms.setHost("smtp.gmail.com");
        ms.setPort(587);
        ms.setUsername("xxxx");
        ms.setPassword("yyyyy");
        ms.setJavaMailProperties(mailProperties);

        message = new SimpleMailMessage();
        message.setSubject("Test email");
        message.setFrom(fromEmail);
        message.setTo(toEmail);
        message.setText("Something something");

        try{
            ms.send(message);
        }
        catch(MailException ex){
            System.err.println(ex.getMessage());
        }
        return "OK";
    }

}

จะทำงานได้ดี (ส่งอีเมล) ด้วย application.properties นี้:

#springboot-starter-mail properties
spring.mail.host=

แต่จะส่งข้อยกเว้นนี้หากฉันลบบรรทัดนั้น:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.mail.javamail.JavaMailSenderImpl] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1373) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1119) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1014) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:545) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE]
    ... 19 common frames omitted

ฉันสามารถทิ้งทรัพย์สินที่ว่างเปล่าไว้ที่นั่นได้ แต่รู้สึกว่าไม่เหมาะสม

มีความคิดอะไรบ้างที่อาจเป็นสาเหตุ?


person Kepa M.    schedule 24.05.2016    source แหล่งที่มา
comment
ทริกเกอร์สำหรับการสร้าง JavaMailSenderImpl คือการมีอยู่ของคุณสมบัติ spring.mail.host การไม่มีสิ่งที่แตกต่างคือการว่างเปล่า นอกจากนี้สิ่งที่คุณกำลังทำอยู่ก็เป็นสิ่งที่คุณไม่ควรทำตั้งแต่แรก หากคุณต้องการการกำหนดค่าจากฐานข้อมูล ให้ทำเช่นนั้น แต่อย่ากำหนดค่า bean ใหม่ขณะรันไทม์ โหลดคุณสมบัติทั้งหมดเมื่อเริ่มต้น (สร้างการใช้งาน PropertySource ที่ขับเคลื่อนด้วย Jdbc) และปล่อยให้สปริงฉีดแทนคุณ ทำไมต้องเป็นฐานข้อมูล? ทำไมไม่ลองใช้ Spring Cloud config หรืออย่างอื่น   -  person M. Deinum    schedule 24.05.2016
comment
@ M.Deinum ขอบคุณมากสำหรับคำอธิบาย ฉันไม่รู้ว่ามันเป็นตัวกระตุ้น เป็นแอปพลิเคชันที่จะอนุญาตให้ผู้ใช้ส่งอีเมลโดยใช้บัญชีอีเมลของตน ข้อมูลนั้นจะถูกบันทึกไว้ในฐานข้อมูลสำหรับผู้ใช้แต่ละคน และนั่นเป็นสาเหตุที่ฉันตั้งค่าคุณสมบัติได้ทันที ฉันไม่รู้ว่าจะมีวิธีแก้ไขปัญหาที่ดีกว่าสำหรับกรณีนี้หรือไม่ ฉันไม่มีความเชี่ยวชาญ ดังนั้นข้อเสนอแนะใดๆ จึงได้รับการชื่นชมอย่างสูง   -  person Kepa M.    schedule 24.05.2016


คำตอบ (2)


เชื่อมต่ออินเทอร์เฟซ JavaMailSender โดยอัตโนมัติแทนการใช้งาน

@Autowired
private JavaMailSender mailSender;
person epdittmer    schedule 24.05.2016
comment
และฉันจะตั้งค่าโฮสต์ พอร์ต ชื่อผู้ใช้ ฯลฯ แบบไดนามิกโดยใช้ JavaMailSender ได้อย่างไร - person Kepa M.; 26.05.2016

อย่าเชื่อมต่อสาย JavaMailSenderImpl โดยอัตโนมัติ ให้สร้างวิธีการที่สร้างและอินสแตนซ์ของ JavaMailSenderImpl และส่งกลับพร้อมกับพารามิเตอร์ทั้งหมดที่คุณต้องการแทน จากนั้นโทรหาผู้ส่งจดหมายของคุณตามที่คุณต้องการ หากคุณเชื่อมต่อผู้ส่งอีเมลโดยอัตโนมัติ ระบบจะแทรกอินสแตนซ์ที่ต้องการพารามิเตอร์ spring.mail.host อยู่แล้ว

person John Smith    schedule 25.05.2016