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在课程路径上
有什么想法?
我不认为aop在私人方法上工作。尝试公开。 – spencergibb
哈哈,就是这样!我知道它必须是那种愚蠢的东西。写下这个答案,我将其标记为已接受的答案。 – jtcotton63
有趣的是:这个Spring Cloud教程页面(https://cloud.spring.io/spring-cloud-aws/)上的sqs侦听器示例具有私有访问权限。这就是我所追求的。 – jtcotton63