java Spring @Autowired 不工作并返回 null
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27840860/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring @Autowired not working and returning null
提问by Haozhe Xie
I have problems on @Autowired
in Spring:
我@Autowired
在 Spring遇到问题:
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;
}
Configuration
配置
<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="[email protected]" />
<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>
As I mentioned above, the mailSender object is always null
in MailService
class.
正如我上面提到的,mailSender 对象总是null
在MailService
类中。
Maybe there's a conflict in mailSender object in MailSender
class and MailService
class. The name of variables are the same, but they are different.
也许MailSender
类和MailService
类中的mailSender 对象存在冲突。变量的名称是相同的,但它们是不同的。
So I tried to rename the variables, but still not working.
所以我试图重命名变量,但仍然无法正常工作。
Unit Test Class:
单元测试类:
@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);
}
}
When I ran the test case, I got following exception:
当我运行测试用例时,出现以下异常:
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
Can you help me with it? Thx.
你能帮我解决吗?谢谢。
回答by sol4me
Your MailService
class is not being managed by spring. One way is to add annotation(Like @Service) to let spring handle it for you. E.g.
你的MailService
班级不是由 spring 管理的。一种方法是添加注释(如@Service)让 spring 为您处理。例如
@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;
}
回答by LeoK
You need to add on the config xml
<context:component-scan base-package="package.of.your.service"/>
您需要添加配置 xml
<context:component-scan base-package="package.of.your.service"/>
in order spring pick this up.
为了春天拿起这个。
From what I can see on your configuration you have only <context:component-scan base-package="com.example.package" />
. My guessing is that this is in a different package.
从我在您的配置中看到的情况来看,您只有<context:component-scan base-package="com.example.package" />
. 我的猜测是这是在不同的包中。
回答by Steve
There are a couple of things wrong in there.
那里有一些问题。
You seem to be using an unfortunate mixture of XML and Java config. Your MailSender
has been annotated as a @Component
, so you don't need to have any XML to define it (assuming that your component scans are defined correctly).
您似乎正在使用 XML 和 Java 配置的不幸混合。您MailSender
已被注释为@Component
,因此您无需使用任何 XML 来定义它(假设您的组件扫描已正确定义)。
Also, it does not have a no-arg constructor, so the mechanism you're trying to use in the XML is not valid.
此外,它没有无参数构造函数,因此您尝试在 XML 中使用的机制无效。
Additionally in the classes which expect it to be autowired, they are putting the @Qualifier("myMailSender")
annotation on the field. The MailSender
has not been named, so there is no MailSender
with that name. You can possibly just remove the @Qualifier
annotation. However if you do need to ensure that it's a specific bean from a multitude of options, then you should name it in the @Controller
annotation like so:
此外,在期望它被自动装配的类中,他们将@Qualifier("myMailSender")
注释放在字段上。在MailSender
还没有被命名,所以没有MailSender
使用该名称。您可以只删除@Qualifier
注释。但是,如果您确实需要确保它是来自多个选项的特定 bean,那么您应该在@Controller
注释中命名它,如下所示:
@Component("myMailSender")