我使用的是 Jersey 2.42。我有一个应用于我的资源方法的注释。
@Path("/stuff")
public class MyResources {
@GET
@MyAnnotation("someValue")
public Response getTheThing(@MyInjectedParam MyType value) {
// ...
}
}
MyAnnotation
是常规方法级注释。没什么特别的。
MyInjectedParam
通过 Feature
配置,如下所示:
public class MyInjectedParamFeature implements Feature {
@Override
public boolean configure(FeatureContext context) {
context.register(new AbstractBinder() {
@Override
protected void configure() {
bindFactory(MyInjectedParamFactory.class)
.to(MyType.class)
.proxy(true)
.proxyForSameScope(false)
.in(RequestScoped.class)
;
bind(MyInjectedParamInjectResolver.class)
.to(new TypeLiteral<InjectionResolver<MyInjectedParam>>(){})
.in(Singleton.class);
}
});
return true;
}
}
工厂正如你所期望的那样:
public class MyInjectedParamFactory implements Factory<MyType> {
@Inject ResourceInfo resourceInfo;
@Override MyType provide() {
// ...MyType construction would like to check for MyAnnotation on the method
// and use its value, but resourceInfo.getResourceMethod() is null!
}
}
但正如评论所说,当调用我的
provide()
方法时,ResourceInfo.getResourceMethod()
调用返回 null
。
有什么方法可以让这两个注解协同工作,以便资源方法参数的注入代码可以访问方法级注解?
我尝试过让
MyAnnotation
成为名称绑定过滤器的触发器,但它遇到了同样的问题。当参数注入发生时,我无法访问过滤器有权访问的任何内容,以便将信息传递给注入代码。
使用这个答案以及调试器的使用,我能够以不同的方式实现这一点,这使我能够访问匹配的
java.lang.reflect.Method
,从而在提供值期间访问其注释。
我将注射更改为使用
ValueParamProvider
,完全按照链接答案中的描述进行。在它的 getValueProvider
方法中,我创建了要返回的巴巴,我可以像这样访问该方法:
import java.util.function.Function;
import org.glassfish.jersey.server.ContainerRequest;
import org.glassfish.jersey.server.model.Parameter;
import org.glassfish.jersey.server.spi.internal.ValueParamProvider;
public class MyInjectedValueParamProvider implements ValueParamProvider {
@Override
public Function<ContainerRequest, ?> getValueProvider(Parameter parameter) {
if (parameter.getRawType().equals(MyType.class)) {
return (ContainerRequest req) -> {
Method resourceMethod = req.getUriInfo().getMatchedResourceMethod().getInvocable().getDefinitionMethod();
// ...now I can look for whatever annotations I need to query to provide
// the correct value
};
}
return null;
}
}