为什么Spring @Configuration类继承不能按预期工作?

时间:2015-07-27 10:12:53

标签: java spring inheritance dependency-injection component-scan

我有一个包含公共bean的抽象Spring配置类:

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

    public abstract String getSpecifics();
}

公共bean的细节由其子类设置:

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

...和...

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

我的测试只需要使用TestConfig,但不应该知道RealConfig(但需要访问realPackage中的其他组件)。它开始于:

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

使用上面的代码,这可以按预期工作并使用"test"细节。但是,如果我颠倒@ComponentScan中的包的顺序,则会使用"real"细节。这令我感到困惑 - 我正在指定TestConfig所以它肯定应该调用重写的方法吗?任何人都可以告诉Spring这样做的原因以及如何解决它?

2 个答案:

答案 0 :(得分:1)

您当前的示例很可能无法编译。 AbstractConfig应该看起来像这段代码片段,但我认为这只是一个复制/粘贴错误。

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

    public abstract String getSpecifics();
}

您正在寻找的功能是@Profile注释(有关详细信息,请参阅https://spring.io/blog/2011/02/14/spring-3-1-m1-introducing-profile)。您需要更改代码,如下所示

RealConfig

package realPackage;
@Configuration
@Profile("real")
public class RealConfig extends AbstractConfig {
...

TestConfig

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

MyIntegrationTestIT

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = TestConfig.class)
@ActiveProfiles("test")
public class MyIntegrationTestIT {
...

答案 1 :(得分:0)

问题原因是由于我对如何通过组件扫描拾取带有@Configuration的bean注释缺乏了解。