2017-09-26 85 views
0

我有一个Spring Boot项目用于接收来自Amazon SQS队列的事件。我一直在使用Spring Cloud AWS项目来简化这一过程。Spring Cloud AWS消息传递包的调用导致依赖bean为空

问题是这样的:Spring Boot应用程序启动就好了,似乎实例化所有必要的bean就好了。但是,当调用使用SqsListener注释的方法时,所有事件处理程序的相关Bean都为null。

另一件值得注意的事情是:我有两种传播事件的方法:1)通过POST Web服务调用,2)通过Amazon SQS。如果我选择使用POST正文中的相同数据将该事件作为POST调用运行,则它工作得很好。只要SimpleMessageListenerContainer调用SQSListener方法,注入的依赖关系就只会是null。

类:

@Service("systemEventsHandler") 
public class SystemEventsHandler { 

    // A service that this handler depends on 
    private CustomService customService; 
    private ObjectMapper objectMapper; 

    @Autowired 
    public SystemEventsHandler(CustomService customService, ObjectMapper objectMapper) { 
     this.matchStatusSvc = matchStatusSvc; 
     this.objectMapper = objectMapper; 
    } 

    public void handleEventFromHttpCall(CustomEventObject event) { 
     // Whenever this method is called, the customService is 
     // present and the method call completes just fine. 
     Assert.notNull(objectMapper, "The objectMapper that was injected was null"); 
     customService.handleEvent(event); 
    } 

    @SqsListener(value = "sqsName", deletionPolicy = SqsMessageDeletionPolicy.ON_SUCCESS) 
    private void handleEventFromSQSQueue(@NotificationMessage String body) throws IOException { 
     // Whenever this method is called, both the objectMapper and 
     // the customService are null, causing the invocation to 
     // fail with a NullPointerException 
     CustomEventObject event = objectMapper.readValue(body, CustomEventObject.class); 
     matchStatusSvc.scoresheetUploaded(matchId); 
    } 
} 

控制器(因为当我选择要运行的事件作为POST)。如上所述,只要我将它作为POST调用运行,它就可以工作。

@RestController 
@RequestMapping("/events") 
public class SystemEventsController { 

    private final SystemEventsHandler sysEventSvc; 

    @Autowired 
    public SystemEventsController(SystemEventsHandler sysEventSvc) { 
     this.sysEventSvc = sysEventSvc; 
    } 

    @RequestMapping(value = "", method = RequestMethod.POST) 
    public void handleCustomEvent(@RequestBody CustomEventObject event) { 
     sysEventSvc.handleEventFromHttpCall(event); 
    } 
} 

相关配置:

@Configuration 
public class AWSSQSConfig { 

    @Bean 
    public SimpleMessageListenerContainer simpleMessageListenerContainer(AmazonSQSAsync amazonSQS) { 
     SimpleMessageListenerContainer msgListenerContainer = simpleMessageListenerContainerFactory(amazonSQS).createSimpleMessageListenerContainer(); 
     msgListenerContainer.setMessageHandler(queueMessageHandler(amazonSQS)); 

     return msgListenerContainer; 
    } 

    @Bean 
    public SimpleMessageListenerContainerFactory simpleMessageListenerContainerFactory(AmazonSQSAsync amazonSQS) { 
     SimpleMessageListenerContainerFactory msgListenerContainerFactory = new SimpleMessageListenerContainerFactory(); 
     msgListenerContainerFactory.setAmazonSqs(amazonSQS); 
     msgListenerContainerFactory.setMaxNumberOfMessages(10); 
     msgListenerContainerFactory.setWaitTimeOut(1); 
     return msgListenerContainerFactory; 
    } 

    @Bean 
    public QueueMessageHandler queueMessageHandler(AmazonSQSAsync amazonSQS) { 
     QueueMessageHandlerFactory queueMsgHandlerFactory = new QueueMessageHandlerFactory(); 
     queueMsgHandlerFactory.setAmazonSqs(amazonSQS); 
     QueueMessageHandler queueMessageHandler = queueMsgHandlerFactory.createQueueMessageHandler(); 
     return queueMessageHandler; 
    } 

    @Bean(name = "amazonSQS", destroyMethod = "shutdown") 
    public AmazonSQSAsync amazonSQSClient() { 
     AmazonSQSAsyncClient awsSQSAsyncClient = new AmazonSQSAsyncClient(new DefaultAWSCredentialsProviderChain()); 
     return awsSQSAsyncClient; 
    } 
} 

其他信息:

  • 春天引导版本:Dalston.RELEASE
  • 春季云AWS版本: 1.2.1.RELEASE
  • 春天云aws自动配置和春天云aws传讯pa ckages在课程路径上

有什么想法?

+1

我不认为aop在私人方法上工作。尝试公开。 – spencergibb

+0

哈哈,就是这样!我知道它必须是那种愚蠢的东西。写下这个答案,我将其标记为已接受的答案。 – jtcotton63

+0

有趣的是:这个Spring Cloud教程页面(https://cloud.spring.io/spring-cloud-aws/)上的sqs侦听器示例具有私有访问权限。这就是我所追求的。 – jtcotton63

回答

0

正如spencergibb在他上面的评论中所建议的那样,将方法的可见性从私有变为公有就行得通。