Steve Chambers Steve Chambers - 1 month ago 9
Java Question

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?

Answer

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.