Search code examples
javaspringinheritancedependency-injectioncomponent-scan

Why is Spring @Configuration class inheritance not working as expected?


I have an abstract Spring configuration class that includes a common bean:

public abstract class AbstractConfig {
    @Bean
    public CommonBean commonBean {
        CommonBean commonBean = new CommonBean();
        commonBean.specifics = getSpecifics();
    };

    public abstract String getSpecifics();
}

The common bean's specifics are set by its subclasses:

package realPackage;
@Configuration
public class RealConfig extends AbstractConfig {
    @Override
    public String getSpecifics() {
        return "real";
    }
}

...and...

package testPackage;
@Configuration
@ComponentScan(basePackages = {"testPackage", "realPackage" })
public class TestConfig extends AbstractConfig {
    @Override
    public String getSpecifics() {
        return "test";
    }
}

My test only needs to use the TestConfig and shouldn't know about the RealConfig (but does need access to other components in realPackage). It begins:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = TestConfig.class)
public class MyIntegrationTestIT { //... }

With the code above, this works as expected and uses the "test" specifics. But if I reverse the order of packages in the @ComponentScan, the "real" specifics are used instead. This is baffling me - am specifying the TestConfig so surely it should be calling the overridden method on this? Could anyone advise as to the reasons Spring does this and how it might be resolved?


Solution

  • The issue turned out to be due to a lack of understanding on my part of how beans annotated with @Configuration are picked up by a component scan.