Инъекция автоуведомленных зависимостей не удалась; Вложенное исключение - org.springframework.beans.factory.BeanCreationException:
Я создаю веб-приложение с помощью Spring, Hibernate, Struts и Maven.
Я получаю следующую ошибку при запуске команды mvn clean install
:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.project.action.PasswordHintActionTest': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.project.action.PasswordHintAction com.project.action.PasswordHintActionTest.action; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.project.action.PasswordHintAction] 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)}
Ниже приведен класс, который имеет зависимость от Autwired:
import com.opensymphony.xwork2.Action;
import org.project.model.User;
import org.proejct.service.UserManager;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.subethamail.wiser.Wiser;
import static org.junit.Assert.*;
public class PasswordHintActionTest extends BaseActionTestCase {
@Autowired
private PasswordHintAction action;
@Autowired
private UserManager userManager;
@Test
public void testExecute() throws Exception {
// start SMTP Server
Wiser wiser = new Wiser();
wiser.setPort(getSmtpPort());
wiser.start();
action.setUsername("user");
assertEquals("success", action.execute());
assertFalse(action.hasActionErrors());
// verify an account information e-mail was sent
wiser.stop();
assertTrue(wiser.getMessages().size() == 1);
// verify that success messages are in the request
assertNotNull(action.getSession().getAttribute("messages"));
}
}
Мой applicationcontext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
default-lazy-init="true">
<!-- Activates scanning of @Autowired -->
<context:annotation-config/>
<!-- Activates scanning of @Repository and @Service -->
<context:component-scan base-package="com.project"/>
<!-- Compass Search Section -->
<!-- Compass Bean, automatically scanning for searchable classes within the model -->
<!-- Hooks into Spring transaction management and stores the index on the file system -->
<bean id="compass" class="org.compass.spring.LocalCompassBean">
<property name="mappingScan" value="org.project"/>
<property name="postProcessor" ref="compassPostProcessor"/>
<property name="transactionManager" ref="transactionManager" />
<property name="settings">
<map>
<entry key="compass.engine.connection" value="target/test-index" />
</map>
</property>
</bean>
Я добавил в свою конфигурацию контекста для сканирования зависимых от Autowired. Но я не уверен, почему он все еще дает это исключение.
Я попытался добавить его следующим образом, но я все равно получаю то же исключение
<context:component-scan base-package="com.project.*"/>
ОБНОВЛЕНИЕ:
Ниже приведено действие подсказки пароля
import org.project.model.User;
import com.project.webapp.util.RequestUtil;
import org.springframework.mail.MailException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import java.util.ArrayList;
import java.util.List;
public class PasswordHintAction extends BaseAction {
private static final long serialVersionUID = -4037514607101222025L;
private String username;
/**
* @param username The username to set.
*/
public void setUsername(String username) {
this.username = username;
}
/**
* Execute sending the password hint via e-mail.
*
* @return success if username works, input if not
*/
public String execute() {
List<Object> args = new ArrayList<Object>();
// ensure that the username has been sent
if (username == null) {
log.warn("Username not specified, notifying user that it a required field.");
args.add(getText("user.username"));
addActionError(getText("errors.requiredField", args));
return INPUT;
}
if (log.isDebugEnabled()) {
log.debug("Processing Password Hint...");
}
// look up the user information
try {
User user = userManager.getUserByUsername(username);
String hint = user.getPasswordHint();
if (hint == null || hint.trim().equals("")) {
log.warn("User '" + username + "' found, but no password hint exists.");
addActionError(getText("login.passwordHint.missing"));
return INPUT;
}
StringBuffer msg = new StringBuffer();
msg.append("Your password hint is: ").append(hint);
msg.append("\n\nLogin at: ").append(RequestUtil.getAppURL(getRequest()));
mailMessage.setTo(user.getEmail());
String subject = '[' + getText("webapp.name") + "] " + getText("user.passwordHint");
mailMessage.setSubject(subject);
mailMessage.setText(msg.toString());
mailEngine.send(mailMessage);
args.add(username);
args.add(user.getEmail());
saveMessage(getText("login.passwordHint.sent", args));
} catch (UsernameNotFoundException e) {
log.warn(e.getMessage());
args.add(username);
addActionError(getText("login.passwordHint.error", args));
getSession().setAttribute("errors", getActionErrors());
return INPUT;
} catch (MailException me) {
addActionError(me.getCause().getLocalizedMessage());
getSession().setAttribute("errors", getActionErrors());
return INPUT;
}
return SUCCESS;
}
}
Обновление 2:
ApplicationContext-struts.xml:
<bean id="passwordHintAction" class="com.project.action.PasswordHintAction" scope="prototype">
<property name="userManager" ref="userManager"/>
<property name="mailEngine" ref="mailEngine"/>
<property name="mailMessage" ref="mailMessage"/>
</bean>
Ответы
Ответ 1
Используйте сканирование компонентов, как указано ниже, если com.project.action.PasswordHintAction
аннотируется аннотациями стереотипов
<context:component-scan base-package="com.project.action"/>
ИЗМЕНИТЬ
Я вижу вашу проблему, в PasswordHintActionTest
вы выполняете автопогрузку PasswordHintAction
. Но вы не создали конфигурацию bean для PasswordHintAction
для autowire. Добавьте одну из аннотаций стереотипа (@Component, @Service, @Controller
) к PasswordHintAction
как
@Component
public class PasswordHintAction extends BaseAction {
private static final long serialVersionUID = -4037514607101222025L;
private String username;
или создать xml-конфигурацию в applicationcontext.xml
, например
<bean id="passwordHintAction" class="com.project.action.PasswordHintAction" />
Ответ 2
Вам нужно предоставить кандидата для автоустройства. Это означает, что экземпляр PasswordHint должен быть известен spring таким образом, чтобы он мог предположить, что он должен ссылаться на него.
Просьба предоставить начальнику класса PasswordHint и/или spring bean определение этого класса для дальнейшей помощи.
Попробуйте изменить имя
PasswordHintAction action;
к
PasswordHintAction passwordHintAction;
чтобы он соответствовал определению bean.