61.8. 動的バインディング
概要
コンテナーフィルターとコンテナーインターセプターをリソースにバインディングする標準的な方法では、フィルターとインターセプターに @Provider
アノテーションを付けます。これにより、バインディングは グローバル: になります。つまり、フィルターとインターセプターはサーバー側の すべて のリソースクラスおよびリソースメソッドにバインドされます。
動的バインディングはサーバー側でバインディングする別の方法で、インターセプターおよびフィルターが適用されるリソースメソッドを選択できます。フィルターおよびインターセプターの動的バインディングを有効にするには、以下に記載されているように、カスタム DynamicFeature
インターフェイスを実装する必要があります。
DynamicFeature インターフェイス
DynamicFeature
インターフェイスは、以下のように javax.ws.rx.container
パッケージで定義されます。
// Java package javax.ws.rs.container; import javax.ws.rs.core.FeatureContext; import javax.ws.rs.ext.ReaderInterceptor; import javax.ws.rs.ext.WriterInterceptor; public interface DynamicFeature { public void configure(ResourceInfo resourceInfo, FeatureContext context); }
動的機能の実装
以下のように動的機能を実装します。
-
上記のように、1 つ以上のコンテナーフィルターまたはコンテナーインターセプターを実装します。ただし、
@Provider
アノテーションを付けないでください (そうしないと、グローバルにバインドされ、動的機能が事実上無関係になります)。 -
DynamicFeature
クラスを実装して、configure
メソッドをオーバーライドすることで、独自の動的な機能を作成します。 -
configure
メソッドでは、resourceInfo
引数を使用して、この機能が呼び出されているリソースクラスとリソースメソッドを検出できます。この情報は、フィルターまたはインターセプターの一部を登録するかどうかを決定するベースとして使用できます。 -
フィルターまたはインターセプターを現在のリソースメソッドに登録する場合は、
context.register
メソッドのいずれかを呼び出します。 -
動的機能クラスに
@Provider
アノテーションを付けて、デプロイメントのスキャンフェーズ中にこれが選択されるようにします。
動的機能の例
以下の例は、@GET
アノテーションが付けられた MyResource
クラス (またはサブクラス) のメソッドに LoggingFilter
フィルターを登録する動的な機能を定義する方法を示しています。
// Java ... import javax.ws.rs.container.DynamicFeature; import javax.ws.rs.container.ResourceInfo; import javax.ws.rs.core.FeatureContext; import javax.ws.rs.ext.Provider; @Provider public class DynamicLoggingFilterFeature implements DynamicFeature { @Override void configure(ResourceInfo resourceInfo, FeatureContext context) { if (MyResource.class.isAssignableFrom(resourceInfo.getResourceClass()) && resourceInfo.getResourceMethod().isAnnotationPresent(GET.class)) { context.register(new LoggingFilter()); } }
動的バインディングプロセス
JAX-RS 標準では、DynamicFeature.configure
メソッドを リソースメソッドごとに 1 度だけ呼び出す 必要があります。つまり、すべてのリソースメソッドは動的機能によってフィルターまたはインターセプターをインストールする可能性がありますが、動的機能を使用して、それぞれの場合にフィルターまたはインターセプターを登録するかどうかを決定します。つまり、動的機能でサポートされるバインディングは、個々のリソースメソッドのレベルで設定されます。
FeatureContext インターフェイス
FeatureContext
インターフェイス ( configure
メソッドでフィルターおよびインターセプターを登録可能) は、以下のように Configurable<>
のサブインターフェイスとして定義されます。
// Java package javax.ws.rs.core; public interface FeatureContext extends Configurable<FeatureContext> { }
Configurable<>
インターフェイスは、以下のようにフィルターおよびインターセプターを 1 つのリソースメソッドに登録するさまざまなメソッドを定義します。
// Java ... package javax.ws.rs.core; import java.util.Map; public interface Configurable<C extends Configurable> { public Configuration getConfiguration(); public C property(String name, Object value); public C register(Class<?> componentClass); public C register(Class<?> componentClass, int priority); public C register(Class<?> componentClass, Class<?>... contracts); public C register(Class<?> componentClass, Map<Class<?>, Integer> contracts); public C register(Object component); public C register(Object component, int priority); public C register(Object component, Class<?>... contracts); public C register(Object component, Map<Class<?>, Integer> contracts); }