11

奇妙な動作が見られます。ここの誰かがこの問題に光を当ててくれることを願っていました。

私の設定を説明することから始めましょう。まず、単純なデータ オブジェクト

public class Apple {
    private String name;
    public Apple withName(String name) {
        this.name = name;
        return this;
    }
    public String getName() {
        return name;
    }
}

そしてテストクラス..

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={TestConfig.class})
public class AppleTest {
    @Autowired private Apple apples;

    @Test
    public void simpleTest() {
        System.out.println("OBJ: "+apples);
    }
}

構成は次のとおりです

@Configuration
public interface ConfigInterface {
    public Apple getApple();
}

実装クラスで

@Configuration
@Import(AbstractTestConfig.class)
public class TestConfig implements ConfigInterface {
    public Apple getApple() {
        return new Apple().withName("Granny apples");
    }
}

構成の依存関係で...

@Configuration
public class AbstractTestConfig {
    @Autowired ConfigInterface conf;

    @Bean Apple myTestApple() {
        return conf.getApple();
    }
}

これはすべてうまくいきます。テストを実行すると、期待どおりの出力が表示されます。しかし、スパナをホイールに投げ込み、AbstractTestConfig を次のように変更します。

@Configuration
public class AbstractTestConfig {
    @Autowired ConfigInterface conf;

    @Bean Apple myTestApple() {
        return conf.getApple();
    }

    // NEW CODE
    @Bean CustomScopeConfigurer scopeConfigurer() {
        return new CustomScopeConfigurer();
    }
}

そして、 Beanを構築する必要があるときに、@Autowiredオブジェクトが突然 null になります。confApple

さらに奇妙なことに、CustomScopeConfigurerBean をTestConfigクラスに移動すると、機能します。

CustomScopeConfigurer特にスコープやオブジェクトについてわからないことはありますか?

4

1 に答える 1

19

Spring @Bean javadocからコピー:

BeanFactoryPostProcessor を返す @Bean メソッド

Spring BeanFactoryPostProcessor (BFPP) タイプを返す @Bean メソッドについては、特別な考慮が必要です。BFPP オブジェクトはコンテナーのライフサイクルの非常に早い段階でインスタンス化する必要があるため、@Configuration クラス内の @Autowired、@Value、@PostConstruct などのアノテーションの処理を妨げる可能性があります。これらのライフサイクルの問題を回避するには、BFPP を返す @Bean メソッドを静的としてマークします。例えば:

@Bean
 public static PropertyPlaceholderConfigurer ppc() {
     // instantiate, configure and return ppc ...
 }

このメソッドを静的としてマークすることにより、宣言する @Configuration クラスのインスタンス化を発生させずに呼び出すことができるため、上記のライフサイクルの競合を回避できます。ただし、前述のように、静的 @Bean メソッドはスコープと AOP セマンティクスに対して拡張されないことに注意してください。通常、他の @Bean メソッドによって参照されないため、これは BFPP のケースでうまくいきます。注意として、BeanFactoryPostProcessor に割り当て可能な戻り値の型を持つ非静的 @Bean メソッドに対して WARN レベルのログ メッセージが発行されます。

于 2013-02-18T18:37:38.727 に答える