【问题标题】:Could not autowire org.springframework.mail.javamail.JavaMailSender无法自动装配 org.springframework.mail.javamail.JavaMailSender
【发布时间】:2014-04-23 14:08:54
【问题描述】:

我在尝试运行我的应用程序时遇到了以下问题。已经调试了一切,但仍然没有。

IDE 正在毫无问题地找到 bean,所以我对这里发生的事情感到非常困惑。

SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mailManager': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void com.testmail.app.service.implement.CustomMManagerService.setMailSender(org.springframework.mail.javamail.JavaMailSender); nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.mail.javamail.JavaMailSender] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}

我的 bean 生成位于以下文件中:

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.testmail.app")
public class WebConfig extends WebMvcConfigurerAdapter {
 //CODE CODE CODE

    @Bean
    public JavaMailSenderImpl mailSender() {
        JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();

        javaMailSender.setProtocol("SMTP");
        javaMailSender.setHost("127.0.0.1");
        javaMailSender.setPort(25);

        return javaMailSender;
    }

// CODE CODE CODE
}

CustomMManager 的代码:

public interface CustomMManager extends Serializable {
    void sendMail(String mailFrom,String mailTo,String subject,String mailBody);
}

最后是 CustomMManagerService 的代码:

@Service("mailManager")
public class CustomMManagerService implements CustomMManager {
    private JavaMailSender mailSender;

    @Autowired
    public void setMailSender(JavaMailSender mailSender) {
        this.mailSender = mailSender;
    }

    @Override
    public void sendMail(final String mailFrom, final String mailTo, final String subject, final String mailBody) {
        try {
            mailSender.send(new MimeMessagePreparator() {
                public void prepare(MimeMessage mimeMessage)
                        throws Exception {
                    MimeMessageHelper message = new MimeMessageHelper(mimeMessage,
                            false, "UTF-8");
                    message.setFrom(mailFrom);
                    message.addTo(mailTo);
                    message.setSubject(subject);
                    message.setText(mailBody, true);
                }
            });
        } catch (MailSendException e) {
            // your codes;
        }
    }
}

非常感谢您的帮助。

【问题讨论】:

  • 你可以试试public JavaMailSender mailSender()
  • WebConfig 中声明的其他 bean 是否工作?
  • 包com.testmail.app下的bean都是?另外,您说 ide 找到了 bean。您是否在 ide 的单元测试中运行它并且一切正常?如果你在 webapp 中运行它,你是如何加载 WebConfig 的?是通过xml还是使用WebApplicationInitializer。
  • public JavaMailSender mailSender() 是我采取的第一个故障排除步骤之一。不工作。 WebConfig 中的所有其他 bean 都可以正常工作。我不使用 XML,所有内容都有注释,所以是 WebApplicationInitializer。
  • 尝试在 Root 上下文中移动您的 bean 声明,而不是在 servlet 上下文中。我认为您的服务是在 Root 上下文中声明的。我说的对吗?

标签: java spring spring-mvc


【解决方案1】:

您可能忘记设置以下属性:

spring.mail.host
spring.mail.username
spring.mail.password
spring.mail.port

【讨论】:

  • 这是最干净的解决方案
  • 这行得通。当我使用 Maven 编译我的应用程序时,它起作用了。但是,当我运行 IDE 时,它给出了错误。添加这些属性后,错误在 IDE 中也消失了!
  • 它有效。但是错误消息几乎没有用。它只是说找不到 bean,但没有说明原因,尽管在平台尝试创建 bean 时很容易抛出有关缺少参数的错误。
【解决方案2】:

根据 mserioli 的评论,答案是 bean 必须在根目录调用的配置文件中声明。

在这种情况下: 移动

@Bean
    public JavaMailSenderImpl mailSender() 

public class ExtraConfig {
@Bean
    public JavaMailSenderImpl mailSender() {
        JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();

        javaMailSender.setProtocol("SMTP");
        javaMailSender.setHost("127.0.0.1");
        javaMailSender.setPort(25);

        return javaMailSender;
    }
}

调用方法:

@Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[]{ExtraConfig.class};
    }

从而解决问题。谢谢大家的帮助。

【讨论】:

  • 我认为 JavaMailSenderImpl 的全部意义在于它可以读取 spring.mail.xxx 属性。在此示例中,所有属性都在 JavaMailSender 上设置。即使它有效,这个解决方案充其量也是令人困惑的。
  • 一点也不,这样您就可以在数据库或文件或其他任何东西上拥有主机、端口和所有内容。当然你可以使用这个配置,但我偶然发现了这个,我真的需要它。
【解决方案3】:
  1. 查看application.properties配置,如:

    spring.mail.host=smtp.xxx.com
    spring.mail.username=xxx@xxx.com
    spring.mail.password=xxxxx
    spring.mail.properties.mail.smtp.auth=true
    spring.mail.properties.mail.smtp.starttls.enable=true
    spring.mail.properties.mail.smtp.starttls.required=true
    
  2. 如果你使用spring-boot,可以检查是否应该使用@EnableAutoConfiguration这个注解

【讨论】:

    【解决方案4】:

    创建 Bean 不要忘记指定邮件属性,用 Java 类或在 application.properties 文件中,例如

    # configuration email
    spring.mail.host=smtp.gmail.com
    spring.mail.port=587
    spring.mail.username=email
    spring.mail.password=password
    spring.mail.properties.mail.smtp.auth=true
    spring.mail.properties.mail.smtp.starttls.enable=true
    spring.mail.properties.mail.smtp.starttls.required=true
    

    【讨论】:

      【解决方案5】:

      如前所述,您需要在应用程序属性中至少设置spring.mail.host。如果设置了属性,则 Spring Boot 自动配置仅创建 JavaMailSender bean:https://github.com/spring-projects/spring-boot/blob/master/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailSenderPropertiesConfiguration.java#L38

      【讨论】:

        【解决方案6】:

        如果您使用application.yml 而不是application.properties 进行配置,请仔细检查您的缩进(YAML 中的结构由缩进决定

        在您的情况下,mail: 应该在 spring: 下,如下所示:

        spring:
          datasource:
            password: root
            url: jdbc:mysql://127.0.0.1:3306/YOU_DATABASE?useSSL=false
            username: root
          mail:
              host: localhost
              port: 1025
              username: 
              password: 
        
              properties:
                mail:
                  smtp:
                    ssl:
                      trust: "*"
                    auth: true
                    starttls:
                      enable: true
                    connectiontimeout: 5000
                    timeout: 3000
                    writetimeout: 5000
        

        【讨论】:

          【解决方案7】:

          您是否尝试过声明您的 bean 返回已实现的接口?像这样的:

          @Bean
          public JavaMailSender mailSender() {
          

          【讨论】:

          • 按照上面已经测试过的cmets,它没有帮助
          • 这应该是我想说的评论。
          【解决方案8】:

          application.properties 中配置 spring.mail 相关属性足以完成 JavaMailSender 的 Autowire。在我们的例子中,有人也有 Bean 声明,因此它优先于 application.properties。因此,Autowired 没有显示。我希望这对您有所帮助。

          【讨论】:

            【解决方案9】:

            就我而言,我删除了一些东西,我的项目没有显示为 maven 项目。 (我将 IntelliJ 用于我的 Spring Boot 应用程序)

            将项目设置为 ma​​ven 项目(关闭并重新打开 IntelliJ。它将显示弹出窗口)修复了该问题。

            【讨论】:

              猜你喜欢
              • 2012-01-27
              • 2016-10-09
              • 2017-08-08
              • 2020-05-04
              • 2014-11-27
              • 1970-01-01
              • 1970-01-01
              • 2018-06-21
              • 2015-07-17
              相关资源
              最近更新 更多