【问题标题】:Why is Spring @Configuration class inheritance not working as expected?为什么 Spring @Configuration 类继承不能按预期工作?
【发布时间】:2015-10-17 11:32:25
【问题描述】:

我有一个包含通用 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 这样做的原因以及如何解决它?

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

    • 谢谢。希望能在此特定上下文中进行更多详细说明。
    • 由于@Configuration 是用@Component 进行元注释的,它也有资格进行组件扫描并被拾取。因此RealConfig 配置bean 被TestConfig 类上的组件扫描拾取。更多信息可以在 Spring 框架文档中找到:docs.spring.io/spring/docs/4.3.26.RELEASE/…
    【解决方案2】:

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

    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)。您需要按如下方式更改代码

    真实配置

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

    测试配置

    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 {
    ...
    

    【讨论】:

      猜你喜欢
      • 2021-05-30
      • 2020-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多