【问题标题】:Different behavior in calling @Bean annotated methods调用 @Bean 注释方法时的不同行为
【发布时间】:2019-09-21 08:32:37
【问题描述】:

我知道在 @Configuration 中将 @Bean 带注释的方法调用为 already discussed

但是我不明白为什么当bean被覆盖时它不起作用。

我有一个无法修改的遗留类。它同时是一个配置和一个业务 bean。这是一个简化版:

@Configuration
public class MyBean {

    String someMethod() {
        return otherBean() + "|" + otherBean();
    }

    int called = 0;

    @Bean
    Object otherBean() {
        return called ++;
    }
}

someMethod() 内部,工厂方法otherBean() 被调用了两次,就@Bean 注释而言,实例应该从Spring 上下文中获取,因此实际代码return called ++; 应该只被调用一次。 someMethod() 的预期输出应始终为 0|0,并且在生产中确实如此。

当我要在单元测试中重新定义 bean 时,麻烦来了:

@SpringJUnitConfig//(MyBean.class)
public class BeanTest {

    @Autowired
    MyBean myBean;

    @Test
    void testIt() {
        assertEquals("0|0", myBean.someMethod());
    }

    @Configuration
    static class TestConfig {    

        @Bean
        MyBean myBean() {
            return new MyBean();
        }
    }
}

原因可能是测试中MyBean实例的一些额外设置(不包括在上面的sn-p中)。

现在,调用 myBean.someMethod() 返回 0|1 而不是 0|0

TestConfig 配置被删除并且测试上下文的配置被设置为@SpringJUnitConfig(MyBean.class) 时,一切都恢复正常(结果为0|0)。

在测试中注册bean有什么不同?

【问题讨论】:

    标签: java spring


    【解决方案1】:

    使用 @Bean 注释的代理方法调用和从 Spring 上下文返回的实例的“魔力”仅发生在配置 bean 中(如这里:@SpringJUnitConfig(MyBean.class))。

    但是当您创建一个新实例为return new MyBean() 时,@Configuration 注释将被忽略,并且该对象被注册为普通 bean (@Bean MyBean myBean()) 而不是配置。这就是为什么调用otherBean() 的方法总是会创建一个新实例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-15
      • 2013-07-19
      • 2021-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-25
      • 1970-01-01
      相关资源
      最近更新 更多