Spring @Autowired 不工作并返回 null
Spring @Autowired not working and returning null
我在 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>
正如我上面提到的,mailSender 对象总是 null
in MailService
class。
可能 MailSender
class 和 MailService
class 中的 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
你能帮我吗?谢谢
您的 MailService
class 不受 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;
}
其中有几处错误。
您似乎使用了 XML 和 Java 配置的不幸混合体。您的 MailSender
已被注释为 @Component
,因此您不需要任何 XML 来定义它(假设您的组件扫描已正确定义)。
此外,它没有无参数构造函数,因此您尝试在 XML 中使用的机制无效。
此外,在希望自动装配的 类 中,他们将 @Qualifier("myMailSender")
注释放在字段上。 MailSender
尚未命名,因此不存在具有该名称的 MailSender
。您可以只删除 @Qualifier
注释。但是,如果您确实需要确保它是来自多个选项的特定 bean,那么您应该在 @Controller
注释中为它命名,如下所示:
@Component("myMailSender")
您需要添加配置 xml
<context:component-scan base-package="package.of.your.service"/>
为了spring拿起这个。
根据我在您的配置中看到的情况,您只有 <context:component-scan base-package="com.example.package" />
。我的猜测是这是在不同的包中。
我在 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>
正如我上面提到的,mailSender 对象总是 null
in MailService
class。
可能 MailSender
class 和 MailService
class 中的 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
你能帮我吗?谢谢
您的 MailService
class 不受 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;
}
其中有几处错误。
您似乎使用了 XML 和 Java 配置的不幸混合体。您的 MailSender
已被注释为 @Component
,因此您不需要任何 XML 来定义它(假设您的组件扫描已正确定义)。
此外,它没有无参数构造函数,因此您尝试在 XML 中使用的机制无效。
此外,在希望自动装配的 类 中,他们将 @Qualifier("myMailSender")
注释放在字段上。 MailSender
尚未命名,因此不存在具有该名称的 MailSender
。您可以只删除 @Qualifier
注释。但是,如果您确实需要确保它是来自多个选项的特定 bean,那么您应该在 @Controller
注释中为它命名,如下所示:
@Component("myMailSender")
您需要添加配置 xml
<context:component-scan base-package="package.of.your.service"/>
为了spring拿起这个。
根据我在您的配置中看到的情况,您只有 <context:component-scan base-package="com.example.package" />
。我的猜测是这是在不同的包中。