源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 @Configuration class MailConfig ( @param:Value ($$"${spring.mail.host} " ) private val host: String, @param:Value ($$"${spring.mail.port} " ) private val port: Int = 0 , @param:Value ($$"${spring.mail.username} " ) private val username: String, @param:Value ($$"${spring.mail.password} " ) private val password: String, @param:Value ($$"${spring.mail.protocol} " ) private val protocol: String ) { @Bean fun javaMailSender () : JavaMailSender { val sender = JavaMailSenderImpl() sender.host = host sender.port = port sender.username = username sender.password = password sender.defaultEncoding = "Utf-8" sender.protocol = protocol return sender } }
运行时报错 Failed to instantiate ... MailConfig$$SpringCGLIB$$0: No default constructor found ,原因是当有默认值时,编译出来的java会生成多个构造器,而spring不知道该用哪个构造器,于是回退尝试调用无参构造器,结果发现不存在,就抛出异常了。
(编译后的java)
解决办法就是不要在bean的构造器上写默认值。此外如果没有引用到其他bean,写成 @Configuration(proxyBeanMethods = false) 禁用bean方法代理的同时提升点性能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 @Configuration(proxyBeanMethods = false) class MailConfig ( @param:Value ($$"${spring.mail.host} " ) private val host: String, @param:Value ($$"${spring.mail.port:0 } " ) private val port: Int , @param:Value ($$"${spring.mail.username} " ) private val username: String, @param:Value ($$"${spring.mail.password} " ) private val password: String, @param:Value ($$"${spring.mail.protocol} " ) private val protocol: String ) { @Bean fun javaMailSender () : JavaMailSender { val sender = JavaMailSenderImpl() sender.host = host sender.port = port sender.username = username sender.password = password sender.defaultEncoding = "Utf-8" sender.protocol = protocol return sender } }