2012-03-13 4 views
12

は、私はそれを呼び出した者を認識している春の豆プロデューサメソッドを作成したいと思いますので、私は次のコードで開始しました:私はは、Beanを取得したい情報を取得できますかCDIのInjectionPointのSpring DIに相当するものは何ですか?

@Configuration 
public class LoggerProvider { 

    @Bean 
    @Scope("prototype") 
    public Logger produceLogger() { 
     // get known WHAT bean/component invoked this producer 
     Class<?> clazz = ... 

     return LoggerFactory.getLogger(clazz); 
    } 
} 

注入?

私は、春の世界でCDI's InjectionPoint相当のものを探しています。

答えて

6

私が知る限り、春にはそのような概念はありません。

次に、処理されるポイントを認識しているのはBeanPostProcessorです。


例:

@Target(PARAMETER) 
@Retention(RUNTIME) 
@Documented 
public @interface Logger {} 

public class LoggerInjectBeanPostProcessor implements BeanPostProcessor { 
    public Logger produceLogger() { 
     // get known WHAT bean/component invoked this producer 
     Class<?> clazz = ...  
     return LoggerFactory.getLogger(clazz); 
    } 


    @Override 
    public Object postProcessBeforeInitialization(final Object bean, 
      final String beanName) throws BeansException { 
     return bean; 
    } 

    @Override 
    public Object postProcessAfterInitialization(final Object bean, 
      final String beanName) throws BeansException { 

     ReflectionUtils.doWithFields(bean.getClass(), 
       new FieldCallback() { 
        @Override 
        public void doWith(final Field field) throws IllegalArgumentException, IllegalAccessException { 
         field.set(bean, produceLogger()); 
        } 
       }, 
       new ReflectionUtils.FieldFilter() { 
        @Override 
        public boolean matches(final Field field) { 
          return field.getAnnotation(Logger.class) != null; 
        } 
       }); 

     return bean; 
    } 
} 
+0

ありがとうラルフ!このBeanPostProcessorは、Beanがどこにでも挿入されるたびに呼び出されます。私が認識できる何らかの方法はありますか**どんな豆が注射されるのですか?私は 'postProcessBeforeInitialization(Object bean、String beanName)'を実行することを意味します。ここで 'bean'はインジェクションをしたいbeanです(私の質問で** who **の部分を尋ねました)。そして' beanName 'は' bean'の名前です。今、私は 'bean 'のどのフィールドが注入を望んでいるのかわかりません。言い換えれば、注入されたbeanが' LoggerProvider'かどうかわかりません。 –

+0

私が理解しているように、ポストプロセッサが呼び出されると、Beanが作成されます。 (どこにも注入されていない)。アイデアは、Beanポストプロセッサの上に独自の小さなインジェクションフレームワークを実装することでした。 – Ralph

+0

これで、Beanが作成されるたびに 'BeanPostProcessor'実装者が呼び出されます。ですから、あなたの考えは 'postProcessBeforeInitialization'を実装することでした。私のカスタム注釈を持っているフィールドを探してみましょう( '@ Logger'と言うことがあります)。そして、リフレクションを通して、自分のカスタムロジックを使ってそのフィールドを初期化します。これはあなたのアプローチですか、それとも私はそれをあまりにも複雑にしましたか?もう一度ありがとう! –

15

春4.3.0は豆生産する方法についてInjectionPointとDependencyDescriptorパラメータを有効にします:

@Configuration 
public class LoggerProvider { 

    @Bean 
    @Scope("prototype") 
    public Logger produceLogger(InjectionPoint injectionPoint) { 
     Class<?> clazz = injectionPoint.getMember().getDeclaringClass(); 

     return LoggerFactory.getLogger(clazz); 
    } 
} 

ところで、この質問にリンクa comment on a blog postからthe issue for this feature SPR-14033リンク。

+0

これを別のBeanに注入すると、これもプロトタイプにスコープされますが、単一の静的インスタンスを共有するのではなく、そのBeanのすべてのインスタンスのロガーが作成されますか? –

+1

@ RupertMadden-Abbottロギングフレームワークは通常、ロガーをキャッシュします。たとえば、SLF4Jロギングフレームワークに関するこの質問を参照してください。[静的コンテキストと非静的コンテキストのSLF4Jロガーを作成するオーバーヘッドは何ですか?](http://stackoverflow.com/questions/10345109/whats-the-overhead-of静的コンテキストと非静的コンテキストとの間のロガーの作成) –

関連する問題