Spring Cloud Stream 和@Publisher 注释兼容性
Spring Cloud Stream and @Publisher annotation compatiblity
由于 Spring Cloud Stream 没有用于向流发送新消息的注释(@SendTo 仅在声明 @StreamListener 时有效),因此我尝试使用 Spring Integration 注释目的,即@Publisher.
因为@Publisher 需要一个通道,并且Spring Cloud Stream 的@EnableBinding 注释可以使用@Output 注释绑定一个输出通道,所以我尝试通过以下方式混合它们:
@EnableBinding(MessageSource.class)
@Service
public class ExampleService {
@Publisher(channel = MessageSource.OUTPUT)
public String sendMessage(String message){
return message;
}
}
此外,我在配置文件中声明了@EnablePublisher 注解:
@SpringBootApplication
@EnablePublisher("")
public class ExampleApplication {
public static void main(String[] args){
SpringApplication.run(ExampleApplication.class, args);
}
}
我的测试:
@RunWith(SpringRunner.class)
@SpringBootTest
public class ExampleServiceTest {
@Autowired
private ExampleService exampleService;
@Test
public void testQueue(){
exampleService.queue("Hi!");
System.out.println("Ready!");
}
}
但我收到以下错误:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.example.ExampleServiceTest': Unsatisfied dependency expressed through field 'exampleService'; nested exception is
org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'exampleService' is expected to be of type 'com.example.ExampleService' but was actually of type 'com.sun.proxy.$Proxy86'
这里的问题是无法注入 ExampleService bean。
有谁知道我该怎么做?
谢谢!
由于您在 ExampleService
中使用了 @Publisher
注释,它被代理用于发布内容。
解决这个问题的唯一方法是为您的 ExampleService
公开一个接口并将该接口注入您的测试 class:
public interface ExampleServiceInterface {
String sendMessage(String message);
}
...
public class ExampleService implements ExampleServiceInterface {
...
@Autowired
private ExampleServiceInterface exampleService;
另一方面,您的 ExampleService.sendMessage()
似乎对消息没有任何作用,因此您可以考虑在某些界面上使用 @MessagingGateway
:https://docs.spring.io/spring-integration/reference/html/messaging-endpoints-chapter.html#gateway
为什么不直接将消息手动发送到流中,如下所示。
@Component
@Configuration
@EnableBinding(Processor.class)
public class Sender {
@Autowired
private Processor processor;
public void send(String message) {
processor.output().send(MessageBuilder.withPayload(message).build());
}
}
您可以通过测试仪进行测试。
@SpringBootTest
public class SenderTest {
@Autowired
private MessageCollector messageCollector;
@Autowired
private Processor processor;
@Autowired
private Sender sender;
@SuppressWarnings("unchecked")
@Test
public void testSend() throws Exception{
sender.send("Hi!");
Message<String> message = (Message<String>) this.messageCollector.forChannel(this.processor.output()).poll(1, TimeUnit.SECONDS);
String messageData = message.getPayload().toString();
System.out.println(messageData);
}
}
您应该会在控制台中看到 "Hi!"。
由于 Spring Cloud Stream 没有用于向流发送新消息的注释(@SendTo 仅在声明 @StreamListener 时有效),因此我尝试使用 Spring Integration 注释目的,即@Publisher.
因为@Publisher 需要一个通道,并且Spring Cloud Stream 的@EnableBinding 注释可以使用@Output 注释绑定一个输出通道,所以我尝试通过以下方式混合它们:
@EnableBinding(MessageSource.class)
@Service
public class ExampleService {
@Publisher(channel = MessageSource.OUTPUT)
public String sendMessage(String message){
return message;
}
}
此外,我在配置文件中声明了@EnablePublisher 注解:
@SpringBootApplication
@EnablePublisher("")
public class ExampleApplication {
public static void main(String[] args){
SpringApplication.run(ExampleApplication.class, args);
}
}
我的测试:
@RunWith(SpringRunner.class)
@SpringBootTest
public class ExampleServiceTest {
@Autowired
private ExampleService exampleService;
@Test
public void testQueue(){
exampleService.queue("Hi!");
System.out.println("Ready!");
}
}
但我收到以下错误:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.example.ExampleServiceTest': Unsatisfied dependency expressed through field 'exampleService'; nested exception is
org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'exampleService' is expected to be of type 'com.example.ExampleService' but was actually of type 'com.sun.proxy.$Proxy86'
这里的问题是无法注入 ExampleService bean。
有谁知道我该怎么做?
谢谢!
由于您在 ExampleService
中使用了 @Publisher
注释,它被代理用于发布内容。
解决这个问题的唯一方法是为您的 ExampleService
公开一个接口并将该接口注入您的测试 class:
public interface ExampleServiceInterface {
String sendMessage(String message);
}
...
public class ExampleService implements ExampleServiceInterface {
...
@Autowired
private ExampleServiceInterface exampleService;
另一方面,您的 ExampleService.sendMessage()
似乎对消息没有任何作用,因此您可以考虑在某些界面上使用 @MessagingGateway
:https://docs.spring.io/spring-integration/reference/html/messaging-endpoints-chapter.html#gateway
为什么不直接将消息手动发送到流中,如下所示。
@Component
@Configuration
@EnableBinding(Processor.class)
public class Sender {
@Autowired
private Processor processor;
public void send(String message) {
processor.output().send(MessageBuilder.withPayload(message).build());
}
}
您可以通过测试仪进行测试。
@SpringBootTest
public class SenderTest {
@Autowired
private MessageCollector messageCollector;
@Autowired
private Processor processor;
@Autowired
private Sender sender;
@SuppressWarnings("unchecked")
@Test
public void testSend() throws Exception{
sender.send("Hi!");
Message<String> message = (Message<String>) this.messageCollector.forChannel(this.processor.output()).poll(1, TimeUnit.SECONDS);
String messageData = message.getPayload().toString();
System.out.println(messageData);
}
}
您应该会在控制台中看到 "Hi!"。