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);
}