调用Spring Cloud AWS Messaging包会导致依赖bean为null

时间:2017-09-26 22:27:31

标签: spring-boot spring-cloud amazon-sqs spring-cloud-aws

我有一个Spring Boot项目,我用它来接收来自Amazon SQS队列的事件。我一直在使用Spring Cloud AWS项目来简化这一过程。

问题在于: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;
    }
}

其他信息:

  • Spring启动版:Dalston.RELEASE
  • Spring cloud AWS版: 1.2.1.RELEASE
  • spring-cloud-aws-autoconfigure和spring-cloud-aws-messaging包都在类路径上

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

正如spencergibb在上面的评论中所建议的那样,将方法的可见性从私人改为公共工作。