Jersey 2.*. How to replace InjectableProvider and AbstractHttpContextInjectable of Jersey 1.*

前端 未结 2 787
借酒劲吻你
借酒劲吻你 2020-12-08 11:22

I would like to create a class whose objects can be injected using the @Context annotation (or better yet a custom annotation for cases where I need to pass an

相关标签:
2条回答
  • 2020-12-08 11:29

    Providing an implementation of InjectionResolver only helps with injection, not when resolving values for the parameters of a resource method.

    At least with Jersey 2.11, you need to define a ValueFactoryProvider annotated with @Provider.

    @Provider
    public class MyValueFactoryProvider implements ValueFactoryProvider {
    
        @Inject
        private MyFactory factory;
    
        @Override
        public Factory<?> getValueFactory(Parameter parameter) {
            if (parameter.getAnnotation(MyAnnotationParam.class) != null) {
                return factory;
            }
    
            return null;
        }
    
        @Override
        public PriorityType getPriority() {
            return Priority.NORMAL;
        }
    
    }
    

    If you also want to get the value injected in, e.g., members and constructor parameters, then InjectionResolver works well.

    0 讨论(0)
  • 2020-12-08 11:47

    You need to implement InjectionResolver<T> interface from HK2. Take a look at existing implementations that are present in Jersey workspace:

    • ContextInjectionResolver handling @Context
    • ParamInjectionResolver handling @PathParam, @QueryParam, ... (via it's subclasses)
    • AutowiredInjectResolver handling @Autowired

    Once you have this, you need to extend AbstractBinder from HK2 and bind your InjectionResolver via it's #configure() method:

    public class MyResolverBinder extends AbstractBinder {
    
        @Override
        protected void configure() {
            bind(MyInjectionResolver.class)
                    .to(new TypeLiteral<InjectionResolver<MyAnnotation>>() {})
                    .in(Singleton.class);
        }
    }
    

    ... and register an instance of this binder in your application class (or via feature):

    Feature:

    public class MyFeature implements Feature {
    
        @Override
        public boolean configure(final FeatureContext context) {
            context.register(new MyResolverBinder());
            return true;
        }
    }
    

    register MyFeature into Application:

    public class JaxRsApplication extends Application {
    
        @Override
        public Set<Class<?>> getClasses() {
            final HashSet<Class<?>> classes = new HashSet<Class<?>>();
            classes.add(MyFeature.class);
            // Register other providers or resources.
            return classes;
        }
    }
    

    register MyResolverBinder or Feature in the ResourceConfig

    new ResourceConfig()
            // Register either MyFeature
            .register(MyFeature.class)
            // or MyResolverBinder
            .register(new MyResolverBinder())
            // Register other providers or resources
            .packages("my.package");
    
    0 讨论(0)
提交回复
热议问题