Show Table of Contents
58.8. Dynamic Binding
Overview
The standard approach to binding container filters and container interceptors to resources is to annotate the filters and interceptors with the
@Provider annotation. This ensures that the binding is global: that is, the filters and interceptors are bound to every resource class and resource method on the server side.
Dynamic binding is an alternative approach to binding on the server side, which enables you to pick and choose which resource methods your interceptors and filters are applied to. To enable dynamic binding for your filters and interceptors, you must implement a custom
DynamicFeature interface, as described here.
DynamicFeature interface
The
DynamicFeature interface is defined in the javax.ws.rx.container package, as follows:
// 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);
}Implementing a dynamic feature
You implement a dynamic feature, as follows:
- Implement one or more container filters or container interceptors, as described previously. But do not annotate them with the
@Providerannotation (otherwise, they would be bound globally, making the dynamic feature effectively irrelevant). - Create your own dynamic feature by implementing the
DynamicFeatureclass, overriding theconfiguremethod. - In the
configuremethod, you can use theresourceInfoargument to discover which resource class and which resource method this feature is being called for. You can use this information as the basis for deciding whether or not to register some of the filters or interceptors. - If you decide to register a filter or an interceptor with the current resource method, you can do so by invoking one of the
context.registermethods. - Remember to annotate your dynamic feature class with the
@Providerannotation, to ensure that it gets picked up during the scanning phase of deployment.
Example dynamic feature
The following example shows you how to define a dynamic feature that registers the
LoggingFilter filter for any method of the MyResource class (or subclass) that is annotated with @GET:
// 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());
}
}Dynamic binding process
The JAX-RS standard requires that the
DynamicFeature.configure method is called exactly once for each resource method. This means that every resource method could potentially have filters or interceptors installed by the dynamic feature, but it is up to the dynamic feature to decide whether to register the filters or interceptors in each case. In other words, the granularity of binding supported by the dynamic feature is at the level of individual resource methods.
FeatureContext interface
The
FeatureContext interface (which enables you to register filters and interceptors in the configure method) is defined as a sub-interface of Configurable<>, as follows:
// Java
package javax.ws.rs.core;
public interface FeatureContext extends Configurable<FeatureContext> {
}
The
Configurable<> interface defines a variety of methods for registering filters and interceptors on a single resource method, as follows:
// 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);
}
Where did the comment section go?
Red Hat's documentation publication system recently went through an upgrade to enable speedier, more mobile-friendly content. We decided to re-evaluate our commenting platform to ensure that it meets your expectations and serves as an optimal feedback mechanism. During this redesign, we invite your input on providing feedback on Red Hat documentation via the discussion platform.