Kesalahan autowire JavaMailSenderImpl jika spring.mail.host tidak ada di application.properties

Saya mengalami sedikit "masalah" dalam menggunakan JavaMailSenderImpl untuk mengirim email di aplikasi booting pegas saya.

Saya mencoba mengatur semua properti secara dinamis (saya ingin properti tersebut dibaca dari DB di masa mendatang) tetapi, untuk alasan yang tidak saya ketahui, pengkabelan otomatis JavaMailSenderImpl hanya berfungsi jika "spring.mail.host" ada di properti aplikasi saya. .

Tidak masalah nilai yang saya tetapkan (bisa kosong, tidak masalah karena nanti saya atur yang benar), tetapi propertinya harus ada atau autowiring akan gagal.

Ini Pengendali saya:

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";
    }

}

Akan berfungsi dengan baik (mengirim email) dengan properti aplikasi ini:

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

Tetapi pengecualian ini akan muncul jika saya menghapus baris itu:

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

Saya bisa meninggalkan properti kosong di sana tetapi rasanya tidak enak.

Adakah yang tahu apa penyebabnya?


person Kepa M.    schedule 24.05.2016    source sumber
comment
Pemicu pembuatan JavaMailSenderImpl adalah adanya properti spring.mail.host. Tidak berada di sana adalah sesuatu yang berbeda dengan menjadi kosong. Selain itu, apa yang Anda lakukan adalah sesuatu yang tidak seharusnya Anda lakukan sejak awal. Jika Anda ingin konfigurasi Anda dari database maka lakukan itu, tetapi jangan mengkonfigurasi ulang kacang saat runtime. Muat semua properti saat startup (buat implementasi PropertySource yang digerakkan oleh Jdbc) dan biarkan pegas melakukan injeksi untuk Anda. Juga mengapa database? Mengapa tidak memasang konfigurasi cloud atau yang lainnya.   -  person M. Deinum    schedule 24.05.2016
comment
@M.Deinum Terima kasih banyak atas penjelasannya, saya tidak tahu itu pemicunya. Ini adalah aplikasi yang memungkinkan pengguna mengirim email menggunakan akun email mereka. Informasi tersebut akan disimpan dalam database untuk setiap pengguna dan itulah sebabnya saya mengatur properti dengan cepat. Saya tidak tahu apakah ada solusi yang lebih baik untuk kasus ini, saya bukan ahlinya jadi saran apa pun sangat kami hargai.   -  person Kepa M.    schedule 24.05.2016


Jawaban (2)


Lakukan autowire antarmuka JavaMailSender alih-alih implementasinya.

@Autowired
private JavaMailSender mailSender;
person epdittmer    schedule 24.05.2016
comment
Dan bagaimana cara mengatur host, port, nama pengguna, dll secara dinamis menggunakan JavaMailSender? - person Kepa M.; 26.05.2016

Jangan melakukan autowire JavaMailSenderImpl. Alih-alih buat metode yang membuat dan membuat instance JavaMailSenderImpl dan mengembalikannya dengan semua parameter yang Anda perlukan. Dan kemudian hubungi pengirim email Anda di mana Anda membutuhkannya. Jika Anda melakukan autowire pada pengirim surat, ia akan memasukkan sebuah instance yang sudah memerlukan parameter spring.mail.host.

person John Smith    schedule 25.05.2016