Spring @Autowired无法正常工作并返回null

时间:2015-01-08 13:05:58

标签: java spring email javamail

我在Spring的@Autowired遇到了问题:

MailSender.java

package com.example.package.util;

@Component
public class MailSender {
    @Autowired
    public MailSender(VelocityEngine velocityEngine, JavaMailSender mailSender) {
        this.velocityEngine = velocityEngine;
        this.mailSender = mailSender;
    }

    public void send() {
        // Dosomething
    }

    private final VelocityEngine velocityEngine;

    private final JavaMailSender mailSender;
}

MailService.java

package com.example.package.service;

@Service
public class MailService {
    public void sendEmail(String email) {
        // mailSender is always null
        String mailBody = mailSender.send();
    }

    // Autowired here is not working
    @Autowired
    @Qualifier("myMailSender")
    private MailSender mailSender;

    // Autowired here is working
    @Autowired
    private UserDao userDao;
}

配置

<context:annotation-config />
<context:component-scan base-package="com.example.package" />

<!-- Mail Service -->
<bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
    <property name="resourceLoaderPath" value="classpath:/mails" />
    <property name="preferFileSystemAccess" value="false" />
</bean>
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
    <property name="host" value="smtp.mailgun.org" />
    <property name="username" value="postmaster@testzilla.org" />
    <property name="password" value="" />
    <property name="javaMailProperties">
        <props>
            <prop key="mail.smtp.auth">true</prop>
            <prop key="mail.smtp.starttls.enable">true</prop>
        </props>
    </property>
</bean>
<bean id="myMailSender" 
        class="com.example.package.service.MailService">
    <property name="mailSender" ref="mailSender" />
</bean>

正如我上面提到的,null类中的mailSender对象始终为MailService

也许MailSender类和MailService类中的mailSender对象存在冲突。变量的名称是相同的,但它们是不同的。

所以我尝试重命名变量,但仍无法正常工作。

单元测试类:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:test-spring-context.xml"})
public class MailSenderTest {
    @Autowired
    @Qualifier("myMailSender")
    private MailSender mailSender;

    @Test
    public void test() {
        String templatePath = "/verifyEmail.vm";
        Map<String, Object> model = new HashMap<String, Object>();

        System.out.println(mailSender);

        String mailBody = mailSender.getMailContent(templatePath, model);
        System.out.println(mailBody);
    }
}

当我运行测试用例时,我遇到以下异常:

Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.example.package.util.MailSender com.example.package.service.UserService.mailSender; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.example.package.util.MailSender] 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), @org.springframework.beans.factory.annotation.Qualifier(value=testzillaMailSender)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
    ... 54 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.example.package.util.MailSender] 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), @org.springframework.beans.factory.annotation.Qualifier(value=testzillaMailSender)}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1308)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1054)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:949)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
    ... 56 more
你可以帮帮我吗? THX。

3 个答案:

答案 0 :(得分:3)

您的MailService课程不受春季管理。一种方法是添加注释(比如@Service)让spring为你处理它。 E.g。

@Service
public class MailService {
    public void sendEmail(String email) {
        String templatePath = "/verifyEmail.vm";
        Map<String, Object> model = new HashMap<String, Object>();
        model.put("email", email);

        // mailSender is always null
        String mailBody = mailSender.getMailContent(templatePath, model);
    }

    // Autowired here is not working
    @Autowired
    private MailSender mailSender;
}

答案 1 :(得分:1)

您需要在config xml上添加 <context:component-scan base-package="package.of.your.service"/>

按顺序弹簧选择它。

从我在配置中看到的内容中,您只有<context:component-scan base-package="com.example.package" />。我的猜测是,这是一个不同的包。

答案 2 :(得分:0)

那里有一些错误。

您似乎正在使用XML和Java配置的不幸混合。您的MailSender已注释为@Component,因此您无需使用任何XML来定义它(假设您的组件扫描已正确定义)。

此外,它没有no-arg构造函数,因此您尝试在XML中使用的机制无效。

此外,在期望自动装配的类中,他们将@Qualifier("myMailSender")注释放在字段上。 MailSender尚未命名,因此没有MailSender具有该名称。您可以删除@Qualifier注释。但是,如果您确实需要确保它是来自众多选项的特定bean,那么您应该在@Controller注释中将其命名为:

@Component("myMailSender")