Using Spring Boot 3.1.5, my main Application class was annotated with both @SpringBootApplication and @ComponentScan. The latter is necessary as we have a multi-module project that needs to exclude certain classes to avoid conflicts.

I am not able to paste our exact class names, so this is an example:

@SpringBootApplication
@ComponentScan(basePackages = "my.company.module",
    excludeFilters = {
        @Filter(type=REGEX, pattern="my\\.company\\.module\\.foo\\..*"),
        @Filter(type=REGEX, pattern="my\\.company\\.module\\.bar\\..*"),
        @Filter(type=REGEX, pattern="my\\.company\\.module\\.baz\\..*")
    },
    nameGenerator = FullyQualifiedAnnotationBeanNameGenerator.class)
public class Application {

This worked fine for scanning all our components and autowiring everything together. After upgrading to Spring Boot 3.2, the component scan seems to be running twice: once on "my.company.module" as expected with the appropriate filters, but then again on a blank package (thus re-scanning all our components and attempting to create them again, causing bean conflicts).

Using a debugger, I traced the change down into ConfigurationClassParser in spring-context, specifically to this line:

Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable( sourceClass.getMetadata(), ComponentScan.class, ComponentScans.class);

This specifically occurs when it is processing the main application class:

In 3.1.5, this set after the function call has 1 entry with an expected base package "my.company.module" member.

In 3.2, this set has 2 entries after the function call, the first with "my.company.module" base package member, and the second with a base package of an empty array.

After doing some more testing, it seems as though starting in 3.2, each @ComponentScan is processed independently even if a package has already been scanned, causing Spring to believe that a component or bean might be duplicated when it isn't.

Ex: If my root package is "my.company" and I do a component scan of "my.company" and in another configuration have a scan of "my.company.foo", a component that appears in my.company.foo package will be detected as a duplicate bean of itself.

Comment From: HzjNeverStop

I encountered the same issue where this incompatible change prevents me from controlling the scanning scope of the @SpringBootApplication annotation using excludeFilters.

I hope that the Spring Boot team can fix this issue in version 3.2.1.

Comment From: quaff

Please share a minimal reproducer.

Comment From: HzjNeverStop

Please share a minimal reproducer.

You can use this project to reproduce this issue: https://github.com/HzjNeverStop/ComponentScanReproducer

The main branch use SpringBoot 3.1.5,ChildBean will not register. Then change the SpringBoot version to 3.2.0,ChildBean will be scan and applicaiton init fail

Comment From: wilkinsona

Thanks for the sample. This appears to be a Spring Framework regression. The failure occurs with Spring Boot 3.1.5 (or 3.1.6) when Spring Framework is upgraded to 6.1. Trying various Framework versions, the problem appears to have been introduced in 6.1.0-M4. We'll transfer this to the Framework team so that they can investigate.

Comment From: HzjNeverStop

Thanks for the sample. This appears to be a Spring Framework regression. The failure occurs with Spring Boot 3.1.5 (or 3.1.6) when Spring Framework is upgraded to 6.1. Trying various Framework versions, the problem appears to have been introduced in 6.1.0-M4. We'll transfer this to the Framework team so that they can investigate.

Thanks,will SpringBoot 3.2.1 upgrade SpringFramework to the fixed version of this issue?

Comment From: snicoll

@HzjNeverStop please refrain from asking questions like that. The issue is opened and you can follow its state right here.

Comment From: snicoll

This seems to be a regression introduced by https://github.com/spring-projects/spring-framework/issues/30941

Comment From: sbrannen

I plan to address this by allowing a directly present @ComponentScan annotation to always take precedence over any meta-present @ComponentScan annotations (such as the one on @SpringBootApplication).

Doing that would still allow us to support the "multiple meta-annotations" use case that we originally sought to support in 6.1 (see #30941).

In addition, the behavior for @ComponentScan would then effectively align with the behavior for @BootstrapWith in spring-test in the sense that a locally declared annotation always overrides a meta-annotation.