1

それは私だけなのか、Spring の Java 構成に欠陥がある例がほとんどなのか疑問に思っています。たとえば、次のようにします。

http://spring.io/blog/2008/03/27/spring-java-configuration-what-s-new-in-m3 http://spring.io/blog/2013/07/18/javaconfig-support -in-the-spring-tool-suite

豆を注入する方法に注目してください。以下のように、メソッドを直接使用しnew OrderRepository(dataSource())ます。

@Configuration
public class ApplicationConfig {

    public @Bean OrderRepository orderRepository() {
        return new OrderRepository(dataSource());
    }

    public @Bean DataSource dataSource() {
        // instantiate and return an new DataSource ...
    }
}

これは私に考えさせられました-2回使用すると2つのオブジェクトが作成されませんか? Springのシングルトン保証を効果的にバイパスしますか? 代わりに豆を注入しないのはなぜですか?依存関係フレームワークは、そもそも機能するように設計されているためです。

簡単なテストをしましょう。たとえば、TestParent と TestedChild の 2 つのクラスを取り上げます。親は子を受け入れます: new TestParent(new TestedChild()). すぐにシングルトン Bean にします。

public class TestedChild { }

public class TestParent {

    private TestedChild child;

    public TestParent(TestedChild child) {
        this.child = child;
    }

    public TestedChild getChild() { return child; }

}

私が見たいのは、コンテキストの初期化中に作成された TestedChild の 2 つの異なるインスタンスを実際に取得できるかどうかです。シングルトン Bean を構成しましょう。

@Configuration
public class TestInjectionConfig {

    @Bean(name = "injected")
    public TestParent injected(TestedChild bean) {
        return new TestParent(bean);
    }

    @Bean(name = "direct")
    public TestParent direct() {
        return new TestParent(testedBean());
    }

    @Bean
    public TestedChild testedBean() {
        return new TestedChild();
    }

}

作成時に同じ TestedChild を注入する必要がある 2 つの異なる TestParent オブジェクトを作成しています。

それらをテストしましょう:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = TestInjectionConfig.class)
public class InjectionApplicationTest {

    @Inject @Named("injected")
    TestParent injected;

    @Inject @Named("direct")
    TestParent direct;

    @Test
    public void instancesShouldBeTheSame() {

        Assert.assertSame(injected, direct);

    }

}

私は豆が同じであることを期待しますが、これは私がSpring 3.2.6で得ているものです:

junit.framework.AssertionFailedError: expected same:<pl.aie.TestParent@59e5a42c> was not:<pl.aie.TestParent@737d72cf>

質問に戻ります。サンプルが Spring 構成クラスでダイレクト メソッド呼び出しを使用しているのはなぜですか? そして、それらがそのように呼び出されることを意図しているのであれば、なぜ @Bean アノテーションが付けられているのでしょうか? それは悪い習慣ですか、それともロジック/コードのどこかに欠陥がありますか?

4

1 に答える 1

5

In your test, you are comparing the two TestParent beans, not the single TestedChild bean.

Also, Spring proxies your @Configuration class so that when you call one of the @Bean annotated methods, it caches the result and always returns the same object on future calls.

See here:

于 2013-12-31T22:39:52.927 に答える