0

I have a Spring Boot application (using Spring Boot 2.4.11) where I'm using Spring Integration. I added the org.springframework.boot:spring-boot-starter-integration and hence I expected @IntegrationComponentScan to be active by default. Indeed, I find Issue 2037 that seems to suggest this. Also, I see that annotation on org.springframework.boot.autoconfigure.integration.IntegrationAutoConfigurationScanRegistrar.IntegrationComponentScanConfiguration.

However, my @MessagingGateway annotated interfaces were not taken up by Spring. I tried to add an explicit @IntegrationComponentScan on one of my @Configuration classes, but it didn't work either.

It started to work once I also specified an explicit basePackages value for that annotation, so:

@Configuration
@IntegrationComponentScan(basePackages = "com.example.app.integration")
public class MyConfigurationClass {
}

and of course my annotated interfaces are in a package below com.example.app.integration.

Am I missing something? I couldn't find any reference to @IntegrationComponentScan in Spring Boot documentation. Other similar annotations (like @EnableJpaRepositories for Spring Data or @EntityScan) are not strictly necessary, unless you need to customize the scanning scope.

I also found Issue 3375, that seems to suggest that I should look at @AutoConfigurationPackage, but:

  • I can't find any mention to this annotation in Spring Boot documentation
  • I suspect this will apply to ANY other "scan" annotation enabled by Spring Boot, so my basePackages in this case must probably point to some package very close to the "root" of my application
  • why isn't this annotation required by other @*Scan annotations like the above ones?
Simeon Leyzerzon
  • 18,658
  • 9
  • 54
  • 82
Mauro Molinari
  • 1,246
  • 2
  • 14
  • 24

1 Answers1

1

I think you need to show your project structure. It works as expected:

  1. I have an interface like com.example.integration.gateway.MyGateway

  2. My main class is in the com.example.integration.IntegrationApplication with a content like:

    @SpringBootApplication
    public class IntegrationApplication {
    

It still works even if I have that MyGateway in the com.example.integration package.

To conclude. The @SpringBootApplication is marked with the @ComponentScan where Spring starts scanning components from the package where this @SpringBootApplication is declared and all the way down to its sub-packages.

If your components are in a different from @SpringBootApplication class, then consider to have it customized via its scanBasePackages property:

/**
 * Base packages to scan for annotated components. Use {@link #scanBasePackageClasses}
 * for a type-safe alternative to String-based package names.
 * <p>
 * <strong>Note:</strong> this setting is an alias for
 * {@link ComponentScan @ComponentScan} only. It has no effect on {@code @Entity}
 * scanning or Spring Data {@link Repository} scanning. For those you should add
 * {@link org.springframework.boot.autoconfigure.domain.EntityScan @EntityScan} and
 * {@code @Enable...Repositories} annotations.
 * @return base packages to scan
 * @since 1.3.0
 */
@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {};

Everything else needs an investigation already inside your project. If you can share that with us, we can take a look and find something.

UPDATE

Turned out when an XML configuration for <int:gateway> is in use, Spring Boot auto-configuration for @IntegrationComponentScan backs-off and requires to be provided explicitly to make @MessagingGateway interfaces to be visible. This problem was fixed in Spring Boot 3.0 as a side-effect of some other fix.

Simeon Leyzerzon
  • 18,658
  • 9
  • 54
  • 82
Artem Bilan
  • 113,505
  • 11
  • 91
  • 118
  • Hi Artem, I discovered what is causing this, although I don't have a reproducing example. Spring Boot 2.7.10 with spring-integration starter: my `@MessagingGateway` annotated bean is autodetected without the need to add anything else. Then, add a XML configuration file (using `@ImportResource`) and in this XML declare an ``: bam! The `@MessagingGateway` bean is not detected any more, unless I add an explicit `@IntegrationComponentScan`! – Mauro Molinari May 05 '23 at 15:07
  • By playing with the devtools I found out that it seems like the problem is this: `IntegrationAutoConfiguration.IntegrationComponentScanConfiguration: Did not match: - @ConditionalOnMissingBean (types: org.springframework.integration.gateway.GatewayProxyFactoryBean; SearchStrategy: all) found beans of type 'org.springframework.integration.gateway.GatewayProxyFactoryBean' &myGateway (OnBeanCondition)`. In other words: by declaring that ``, the `IntegrationComponentScanConfiguration` gets disabled. Why can't both techniques (gateways in XML and annotated gateways) live together? – Mauro Molinari May 05 '23 at 15:08
  • Was fixed in Spring Boot `3.0`: https://github.com/spring-projects/spring-boot/commit/95557ddbc6a8cae55aba85ca7d5d21078a3bc105 – Artem Bilan May 05 '23 at 16:25
  • Thank you Artem! If you promote your last comment as an answer or change the above one, I will mark it as the accepted answer! – Mauro Molinari May 05 '23 at 20:32
  • Sure! Added an UPDATE into my answer. – Artem Bilan May 08 '23 at 12:55