2016-11-17 19 views
2

次のコードは春4でうまく動作しますが、getBean(FooService.class)がすでにロードされたBeanを返すのはなぜだろうかと思います。私は、Beanのロードの順序が保証されていないと考えました。つまり、nullのBeanを取得することが可能です。それはローディングターゲットが文字列ではないクラス(つまりオブジェクト)であるか、FooService Beanにプロトタイプのような特別なスコープがあるためですか?もしそうなら、getBean(クラス)とgetBean(オブジェクト)手始めにこのbeanがnullでない理由

public abstract class AbstractService implements ApplicationContextAware { 
    protected ApplicationContext applicationContext; 

    protected FooService fooService; 

    @Override 
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 
     this.applicationContext = applicationContext; 
    } 

    @PostConstruct 
    protected void postConstruct() { 
     fooService = applicationContext.getBean(FooServiceImpl.class); 
    } 
+0

私はnullのオブジェクトを取得しないように春の感覚だと思います – XtremeBaumer

+0

実際に私は* bean **が** null **と思うのですが、特定のbeanオブジェクトをロードするために* applicationContext *を使用します。春は必要ありません。 * @ Autowired *アノテーションは、Beanパラメータで使用することも、Beanがパラメータであるクラスコンストラクタや* set *メソッドでよりうまく使用することもできます。 –

答えて

0

の違いは何ですか、文字列は、あなたが自分で作成することができますどのように、完全な権利クラスです。

fooServiceで何かを取得している理由は、ApplicationContext getBean methodが渡している引数に従ってマネージドBeanを取得できることです。

それはBeanを取得することができなかった場合は、これらの例外のいくつか得ることができます:

例外:NoSuchBeanDefinitionExceptionを - 指定された型 のないBeanはNoUniqueBeanDefinitionExceptionを発見されなかった場合 - 複数の豆場合 所与のタイプはBeansExceptionを発見した - それは、すでに作成されていない場合Beanは が作成できなかった場合

+0

しかし、Beanが初期化されていない、つまりコンテキストにロードされていない場合、このBeanはFooService Beanより前に初期化されます。このようにして、getBeanはnullを返します。 – Tiina

+0

私の編集をご覧ください。 – Andres

+0

それは本当ですか、そのapplicationContext.getBean(...)Autowired(ちょうど)と同じです、その春は、その定義を見つけることができる場合、1つのBeanを返すようになりますか? – Tiina

1

ApplicationContext::getBeanメソッドは、指定されたタイプのBeanを作成します。

@Component 
public class Bean1 { 

    @Autowired 
    private ApplicationContext applicationContext; 

    public Bean1() { 
     System.out.println("Bean 1 constructor"); 
    } 

    @PostConstruct 
    public void init() { 
     System.out.println("Bean 1 @PostConstruct started"); 
     applicationContext.getBean(Bean2.class); 
     System.out.println("Bean 1 @PostConstruct completed"); 
    } 
} 

@Component 
public class Bean2 { 

    @Autowired 
    private ApplicationContext applicationContext; 

    public Bean2() { 
     System.out.println("Bean 2 constructor"); 
    } 

    @PostConstruct 
    public void init() { 
     System.out.println("Bean 2 @PostConstruct started"); 
     applicationContext.getBean(Bean1.class); 
     System.out.println("Bean 2 @PostConstruct completed"); 
    } 
} 

コンテキスト初期化中の印刷出力である:異なるgetBean方法として

Bean 1 constructor 
Bean 1 @PostConstruct started 
Bean 2 constructor 
Bean 2 @PostConstruct started 
Bean 2 @PostConstruct completed 
Bean 1 @PostConstruct completed 

、あなたがクラスを渡す場合、正確に一つの豆次の二つのBeanクラスについて

そのクラスの複数のBeanインスタンスのどれがあなたが求めているのではないかということではありませんが、名前による検索では特定の名前付きBeanインスタンスを取得できます。

+0

公式文書が "@PostConstructメソッドをサポートしています。これは、すべてのBeanが作成された後に呼び出されます。"そのコメントに基づいて、このBeanが構築された直後にpostConstructが呼び出されます。そして、私は、すべての豆は次々に造られていると思います。もう少し証拠をお願いします:) – Tiina

+0

@Tiinaあなたは正しいようですが、明示的にautowiredではない豆がこの時点で作成されているという保証はありません。私は私の答えを編集しました。 –

+0

@Dragon Bozanovicは非常にクリアです。 :) – Tiina

関連する問題