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. 上記のように、1 つ以上のコンテナーフィルターまたはコンテナーインターセプターを実装します。ただし、@Provider アノテーションを付けないでください (そうしないと、グローバルにバインドされ、動的機能が事実上無関係になります)。
  2. DynamicFeature クラスを実装して、configure メソッドをオーバーライドすることで、独自の動的な機能を作成します。
  3. configure メソッドでは、resourceInfo 引数を使用して、この機能が呼び出されているリソースクラスとリソースメソッドを検出できます。この情報は、フィルターまたはインターセプターの一部を登録するかどうかを決定するベースとして使用できます。
  4. フィルターまたはインターセプターを現在のリソースメソッドに登録する場合は、context.register メソッドのいずれかを呼び出します。
  5. 動的機能クラスに @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);
}