Я пытаюсь заставить Spring заменить класс, который имеет автосвязанные зависимости, на другой (тестовый класс), который не имеет этих автопроводных зависимостей, но я всегда получаю исключение NoSuchBeanDefinitionException, например:
Вызывается: org.springframework.beans.factory.NoSuchBeanDefinitionException: нет доступного квалифицирующего компонента типа com.experiment.beanreplacement.client.Connection: ожидается как минимум 1 компонент, который считается кандидатом на автоматическое подключение.Аннотации зависимостей: {@ org.springframework.beans.factory.annotation.Autowired (обязательно = true)}
Я создал упрощенный пример, чтобы показать мою проблему.
У меня есть два класса вмой клиентский пакет (Connection.java и TcpClient.java) и два в моем прикладном пакете (MessageSender.java и Scheduler.java)
package com.experiments.beanreplacement.client;
@Component
public class Connection {
public void send(String msg) { System.out.println("Connection send: " + msg); }
...
TcpClient.java автоматически связывает класс Connection:
@Component
public class TcpClient {
@Autowired
Connection connection;
public void send(String msg) {
System.out.println("TcpClient send");
connection.send(START_OF_MESSAGE + msg + END_OF_MESSAGE);
}
}
Класс MessageSender использует TcpClient для отправки сообщений:
package com.experiments.beanreplacement.application;
@Component
public class MessageSender {
@Autowired
TcpClient client;
public void sendAMessage() {
client.send("Hello world!");
client.send("Bye bye...");
}
}
Я настроил тест для запуска этого с использованием JUnit:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"/applicationContext.xml"})
public class MessageSenderTest {
@Autowired
MessageSender messageSender;
@Test
public void testMessageSender() {
messageSender.sendAMessage();
}
}
Класс TcpClientMock:
package client;
@Primary
public class TcpClientMock extends com.experiments.beanreplacement.client.TcpClient{
@Override
public void send(String msg) {
System.out.println("Mock client send: " + msg);
}
...
applicationContext.xml
<bean class="client.TcpClientMock" name="client" >
</bean>
<context:component-scan base-package="com.experiments.beanreplacement.application">
</context:component-scan>
...
В файле applicationContext.xml я заменяю TcpClient, который автоматически подключается в классе MessageSender, на другой (TcpClientMock).
Я настроил компонентное сканирование таким образом, чтобы он смотрел только на пути MessageSender и TcpClientMock, надеясь избежать необходимости иметь дело с зависимостями autowire исходного TcpClient и базового Connection.
Тем не менее, я все еще получаю «Нет подходящего бина типа com.experiment.beanreplacement.client.Connection»: ожидается как минимум 1 бин, который квалифицируется как кандидат для автопроводки ».ошибка, даже если класс, использующий зависимость autowire, не является частью компонентаного сканирования.
Есть ли способ избежать этого?