覆盖bean定义无法按预期工作

时间:2015-07-17 13:22:26

标签: spring spring-bean

我对Spring基于注释的配置感到困惑。

我有一个接口MyInterface和两个实现此接口的类(MyClass1和MyClass2)。

@Component("MyInterface")
public class MyClass1 implements MyInterface {

    public void execute() {
        System.out.println("MyClass1 executed");
    }
}

public class MyClass2 implements MyInterface {

    public void execute() {
        System.out.println("MyClass2 executed");
    }
}

MyClass1是使用Component-Scan创建的,MyClass2被定义为bean:

@Configuration
@ComponentScan(basePackageClasses = MyClass1Configuration.class)
public class MyClass1Configuration {

}

@Configuration
public class MyClass2Configuration {

    @Bean(name = "MyInterface")
    public MyInterface myClass2() {
        return new MyClass2();
    }
}

我使用Spring Test的ContextConfiguration批注构建应用程序上下文:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {MyClass1Configuration.class, MyClass2Configuration.class})
public class SpringTestCase1 {

    @Autowired
    private MyInterface myInterface;

    @Test
    public void testMethod() {
        System.out.println("testMethod invoked");
        Assert.assertEquals(MyClass2.class, myInterface.getClass());
        myInterface.execute();
    }
}

不幸的是,测试失败,因为Class1是自动装配而不是Class2。预期的行为是MyClass2Configuration覆盖由MyClass1Configuration定义的bean。我的错是什么。

我在GitHub上创建了这个例子,如果你想看看一个有效的例子: https://github.com/OLibutzki/spring-test-configuration/tree/master/simple-sprint-test

感谢您的帮助。

亲切的问候 奥利弗

3 个答案:

答案 0 :(得分:3)

你很接近......首先,你不能在同一个Spring环境中拥有2个具有相同名称的bean,除非你特意允许它,我不推荐它,因为它&不#39;容易出错。

除此之外,您应该使用@Primary annotation,它可以在方法和类型级别应用。在您的情况下,您应该在MyClass2Configuration

中的方法级别应用它
@Configuration
public class MyClass2Configuration {

    @Bean
    @Primary
    public MyInterface myClass2() {
        return new MyClass2();
    }
}

当您按类型(而不是按名称)进行自动装配时,对于专门允许覆盖bean定义似乎没有用处。您可以让两个bean都在Spring上下文中,然后,通过@Primary注释,Spring将自动装配您的主要内容。 bean实例。

答案 1 :(得分:1)

或者您可以使用

覆盖

  

spring.main.allow-bean-definition-overriding = true

在main / resource / application.properties中

但这是容易出错的

答案 2 :(得分:0)

某些春季版本出现问题,我尝试将版本从2.1.3更改为2.0.2.RELEASE。它开始工作了