Java 为什么我的处理程序方法在定义为lambda时没有被触发?

Java 为什么我的处理程序方法在定义为lambda时没有被触发?,java,lambda,spring-integration,spring-integration-dsl,spring-integration-aws,Java,Lambda,Spring Integration,Spring Integration Dsl,Spring Integration Aws,我用DSL语法定义了一个从SFTP流到S3的IntegrationFlow,如下所示: 返回IntegrationFlows.fromstp.inboundStreamingAdapterremoteFileTemplate .remoteDirectoryremoteDirectory, e->e.pollerPollers.fixedDelayPOLL,TimeUnit.SECONDS .新的流线型变压器 .handles3UploadMessageHandleroutputFolderPa

我用DSL语法定义了一个从SFTP流到S3的IntegrationFlow,如下所示:

返回IntegrationFlows.fromstp.inboundStreamingAdapterremoteFileTemplate .remoteDirectoryremoteDirectory, e->e.pollerPollers.fixedDelayPOLL,TimeUnit.SECONDS .新的流线型变压器 .handles3UploadMessageHandleroutputFolderPath,头文件['file\u remoteFile']//在S3上上载 收到 私有S3MessageHandler s3UploadMessageHandlerString folderPath,String spelFileName{ S3MessageHandler S3MessageHandler=新的S3MessageHandleramazonS3,s3ConfigProperties.GetBucket.getCardManagementData; s3MessageHandler.setKeyExpressionnew SpelExpressionParser.parseExpressionString.format“%s/”.concat%s,folderPath,spelFileName; s3MessageHandler.setCommandS3MessageHandler.Command.UPLOAD; 返回s3MessageHandler; } 它按预期工作:文件很好地上传到我的S3存储桶中。但是,我希望避免使用SPEL语法,并将消息中的头注入s3uploadMessageHandler方法,这样我就可以使用一个简单的ValueExpression在s3uploadMessageHandler方法中设置keyExpression。 为了做到这一点,我改变了

handles3UploadMessageHandleroutputFolderPath,标题['file\u remoteFile']//在S3上上载 到

handlem->s3UploadMessageHandleroutputFolderPath,字符串m.getHeaders.getfile\u remoteFile//在S3上上载 但是现在这个处理器似乎不再被触发了。日志中没有错误,我从日志中知道SFTP轮询仍在工作

我试图找到这背后的原因,我发现在IntegrationFlowdefinition.java中输入handle方法时,messageHandler类类型不同:在不使用lambda调用时,它是S3MessageHandler,在使用lambda表达式调用时,它是MyCallingClass$lambda


我错过了什么使我的场景工作?

有两种方法来处理消息。一种是通过MessageHandler实现——这是最有效的方法,在通道适配器实现框架中完成,如S3MessageHandler。另一种方法是POJO方法调用——当您不需要担心任何框架接口时,这是最用户友好的方法

所以,当你这样使用它时。handles3UploadMessageHandler。。。您引用了MessageHandler,框架知道必须注册该MessageHandler的bean,因为您的s3UploadMessageHandler不是@bean

当您将其用作lambda时,框架将其视为POJO方法调用,并且有一个为MethodInvokingMessageHandler注册的bean,但不是您的S3MessageHandler

无论如何,即使您将s3UploadMessageHandler更改为@Bean方法,它也不会起作用,因为您不允许框架调用S3MessageHandler.handleMessage。这里要做的就是在运行时调用该私有方法,针对每个请求消息创建一个S3MessageHandler实例:MethodInvokingMessageHandler在其handleMessage中调用您的lambda,仅此而已—S3不会发生任何事情


ValueExpression在此无法帮助您,因为您需要根据每个请求消息计算目标文件。因此,您需要一个运行时表达式。新的SpelExpressionParser.parseExpression确实没有什么问题。只是因为我们没有选择,只能有一个无状态的S3MessageHandler,而不是像您尝试使用可疑的lambda和ValueExpression那样在运行时对每个请求重新创建它。

有两种方法来处理消息。一种是通过MessageHandler实现——这是最有效的方法,在通道适配器实现框架中完成,如S3MessageHandler。另一种方法是POJO方法调用——当您不需要担心任何框架接口时,这是最用户友好的方法

所以,当你这样使用它时。handles3UploadMessageHandler。。。您引用了MessageHandler,框架知道必须注册该MessageHandler的bean,因为您的s3UploadMessageHandler不是@bean

当您将其用作lambda时,框架将其视为POJO方法调用,并且有一个为MethodInvokingMessageHandler注册的bean,但不是您的S3MessageHandler

无论如何,即使您将s3UploadMessageHandler更改为@Bean方法,它也不会起作用,因为您不允许框架调用S3MessageHandler.handleMessage。这里要做的就是在运行时调用该私有方法,针对每个请求消息创建一个S3MessageHandler实例:MethodInvokingMessageHandler在其handleMessage中调用您的lambda,仅此而已—S3不会发生任何事情

卡诺的价值表达
这里没有帮助,因为您需要根据每个请求消息评估目标文件。因此,您需要一个运行时表达式。新的SpelExpressionParser.parseExpression确实没有什么问题。只是因为我们没有选择,只能有一个无状态S3MessageHandler,并且不能像您使用可疑的lambda和ValueExpression那样在运行时根据每个请求重新创建它。

非常感谢@Artem Bilan,您的解释非常清楚;非常感谢@Artem Bilan,您的解释非常清楚;