javaspringspring-integrationspring-integration-aws

How can I inject a bean into an @InboundChannelAdapter?


Considering that a method annotated with @InboundChannelAdapter can't accept any parameters for some reason, how can I inject a bean? The channel property of this annotation already references a bean, so why can't I reference any other bean?

For my specific case, I'm using spring-integration-aws to poll a S3 bucket. The InboundChannelAdapter is declared as follows:

    @Bean
    @InboundChannelAdapter(channel = "s3Channel", poller = @Poller(fixedDelay = "1000"))
    public MessageSource<InputStream> s3InboundStreamingMessageSource() {
        S3StreamingMessageSource messageSource = new S3StreamingMessageSource(template(s3client()));
        // more config here
        return messageSource;
    }

What bothers me is that I must call the s3client() method to get a S3Client instance, but I'd rather obtain it as a bean since it can be shared.

How do I achieve that?


Solution

  • Just tested it and that works well:

        @Bean
        S3Client s3Client() {
            return S3;
        }
    
        @Bean
        @InboundChannelAdapter(value = "s3FilesChannel", poller = @Poller(fixedDelay = "100"))
        public S3StreamingMessageSource s3InboundStreamingMessageSource(S3Client s3Client) {
            S3SessionFactory s3SessionFactory = new S3SessionFactory(s3Client);
            S3RemoteFileTemplate s3FileTemplate = new S3RemoteFileTemplate(s3SessionFactory);
            S3StreamingMessageSource s3MessageSource =
                    new S3StreamingMessageSource(s3FileTemplate, Comparator.comparing(S3Object::key));
            s3MessageSource.setRemoteDirectory("/" + S3_BUCKET + "/subdir");
            s3MessageSource.setFilter(new S3PersistentAcceptOnceFileListFilter(new SimpleMetadataStore(), "streaming"));
    
            return s3MessageSource;
        }
    

    Pay attention how I inject S3Client as a bean method argument.

    Right, my IntelliJ IDEA complains:

    enter image description here

    But that's because it is only aware of the @InboundChannelAdapter, but doesn't take into account that there is a @Bean as well.

    So, in other words, any @Bean method definition works as it is expected by Spring Framework.