web-dev-qa-db-ja.com

JSR 330で@Injectをオプションにできますか(@Autowire(required = false)など)?

Springの_@Autowire_は、一致するautowire候補が見つからない場合にSpringがエラーをスローしないように構成できます:@Autowire(required=false)

同等のJSR-330アノテーションはありますか?一致する候補がない場合、_@Inject_は常に失敗します。 _@Inject_を使用して、一致するタイプが見つからない場合にフレームワークが失敗しないようにする方法はありますか?私はその程度のドキュメントを見つけることができませんでした。

27
Eric B.

いいえ... JSR 330のオプションに相当するものはありません...オプションの注入を使用する場合は、フレームワーク固有の@Autowiredアノテーションを使用する必要があります

15
Arun P Johny

Java.util.Optionalを使用できます。 Java 8を使用していて、Springのバージョンが4.1以上( ここ を参照)、代わりに

@Autowired(required = false)
private SomeBean someBean;

Java 8に付属のJava.util.Optionalクラスを使用できます。次のように使用します。

@Inject
private Optional<SomeBean> someBean;

このインスタンスは決してnullにはならず、次のように使用できます。

if (someBean.isPresent()) {
   // do your thing
}

このように、一部のBeanが必要で一部のBeanがオプションであるコンストラクター注入も実行できるため、柔軟性が非常に高くなります。

注:残念ながら、SpringはGuavacom.google.common.base.Optionalこちら を参照)をサポートしていないため、このメソッドは機能しますJava 8(またはそれ以上)を使用している場合のみ。

33
Utku Özdemir

インスタンスインジェクションは見過ごされがちです。それは大きな柔軟性を追加します。取得する前に、依存関係の可用性を確認してください。不満足なgetは、高価な例外をスローします。使用する:

@Inject
Instance<SomeType> instance;
SomeType instantiation;

if (!instance.isUnsatisfied()) {
    instantiation = instance.get();
}

通常どおり注入候補を制限できます。

@Inject
@SomeAnnotation
Instance<SomeType> instance;
10
Steve Brewin

オプションの注入ポイントを作成することが可能です!

http://docs.jboss.org/weld/reference/latest/en-US/html/injection.html#lookup に記載されているように、注入ルックアップを使用する必要があります

@Inject
Instance<Type> instance;

// In the code
try {
   instance.get();
}catch (Exception e){

}

またはタイプのすべてのインスタンス

@Inject
Instance<List<Type>> instances

また、必要に応じてget()メソッドは遅延評価されます。デフォルトのInjectionは起動時に評価され、注入できるBeanが見つからない場合は例外をスローします。もちろん、実行時にBeanが注入されますが、これが不可能な場合、アプリケーションは起動しません。ドキュメントには、注入されたインスタンスのフィルタリング方法など、さらに多くの例が含まれています。

6
Giovanni Silva

AutowiredAnnotationBeanFactoryPostProcessor(Spring 3.2)には、サポートされている「Autowire」アノテーションが必要かどうかを判断するためのこのメソッドが含まれています。

_    /**
     * Determine if the annotated field or method requires its dependency.
     * <p>A 'required' dependency means that autowiring should fail when no beans
     * are found. Otherwise, the autowiring process will simply bypass the field
     * or method when no beans are found.
     * @param annotation the Autowired annotation
     * @return whether the annotation indicates that a dependency is required
     */
    protected boolean determineRequiredStatus(Annotation annotation) {
        try {
            Method method = ReflectionUtils.findMethod(annotation.annotationType(), this.requiredParameterName);
            if (method == null) {
                // annotations like @Inject and @Value don't have a method (attribute) named "required"
                // -> default to required status
                return true;
            }
            return (this.requiredParameterValue == (Boolean) ReflectionUtils.invokeMethod(method, annotation));
        }
        catch (Exception ex) {
            // an exception was thrown during reflective invocation of the required attribute
            // -> default to required status
            return true;
        }
    }
_

つまり、デフォルトではありません。

デフォルトで検索されるメソッド名は「必須」ですが、これは_@Inject_アノテーションのフィールドではないため、methodnullおよびtrueが返されます。

これを変更するには、このBeanPostProcessorをサブクラス化し、determineRequiredStatus(Annotation)メソッドをオーバーライドして、trueまたはよりスマートなものを返すようにします。

5