代码之家  ›  专栏  ›  技术社区  ›  italktothewind

Spring Cloud Stream与@Publisher注释的兼容性

  •  2
  • italktothewind  · 技术社区  · 7 年前

    由于Spring Cloud Stream没有用于向流发送新消息的注释(@SendTo仅在声明@StreamListener时有效),因此我尝试使用Spring集成注释,即@Publisher。

    因为@Publisher接受一个通道,Spring Cloud Stream的@EnableBinding注释可以使用@output annotation绑定一个输出通道,所以我尝试用以下方式混合它们:

    @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'
    

    这里的问题是exampleServicebean不能被注入。

    谢谢

    1 回复  |  直到 7 年前
        1
  •  2
  •   Artem Bilan    7 年前

    因为你用的是 @Publisher 在您的 ExampleService

    解决此问题的唯一方法是为您的应用程序公开一个接口 并将其注入到测试类中:

    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

        2
  •  1
  •   Michael Ouyang    6 年前

    为什么不直接手动将消息发送到流,如下所示。

    @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);
    
        }
    
    }
    

    您应该在控制台中看到“嗨!”。