Dependency injection Jersey@Context范围

Dependency injection Jersey@Context范围,dependency-injection,jersey,jax-rs,Dependency Injection,Jersey,Jax Rs,我很难理解泽西的注射机理。JAX-RS规范()指出,可以在应用程序子类、根资源类和提供者中通过@Context进行注入 我现在有一个在启动时被实例化的类,并且有一个在每个请求中都被调用的方法。在方法内部,我需要访问当前的UriInfo对象。问题是,这个方法不是从我的代码中调用的。因此,我无法将UriInfo直接传递给该方法 实际上我想做这样的事情: 公共类MyClass实现第三方接口{ //不可能,因为类不是应用程序子类、根资源类或提供程序 @上下文 私人UriInfo UriInfo; pu

我很难理解泽西的注射机理。JAX-RS规范()指出,可以在应用程序子类、根资源类和提供者中通过@Context进行注入

我现在有一个在启动时被实例化的类,并且有一个在每个请求中都被调用的方法。在方法内部,我需要访问当前的UriInfo对象。问题是,这个方法不是从我的代码中调用的。因此,我无法将UriInfo直接传递给该方法

实际上我想做这样的事情:

公共类MyClass实现第三方接口{
//不可能,因为类不是应用程序子类、根资源类或提供程序
@上下文
私人UriInfo UriInfo;
public void方法callebythirdpartycode(){
Uri requestUri=uriInfo.getRequestUri();
//做点什么
}
}
我试过这个。显然没有成功:

公共类MyClass实现第三方接口{
私人UriInfo UriInfo;
公共MyClass(UriInfo UriInfo){
this.uriInfo=uriInfo;
}
public void方法callebythirdpartycode(){
Uri requestUri=uriInfo.getRequestUri();
//做点什么
}
}
@提供者
@生成(MediaType.WILDCARD)
公共类MyBodyWriter实现MessageBodyWriter{
@上下文
私人UriInfo UriInfo;
私人MyClass MyClass;
私人第三方课堂第三方课堂;
公共MyBodyWriter(){
//uriInfo此时为空:(
myClass=新的myClass(uriInfo);
第三方类=新的第三方类();
第三方类注册表(myClass);
}
public void writeTo(最终MyView视图、最终类类型,/*等*/)抛出IOException、WebApplicationException{
//execute()调用MyClass#MethodCallebythirdPartyCode()
第三方类。execute();
}
}
我能想到的唯一解决办法是这个。我认为它不是很干净:

公共类MyClass实现第三方接口{
私人UriInfo UriInfo;
公共无效设置UriInfo(最终UriInfo UriInfo){
this.uriInfo=uriInfo;
}
public void方法callebythirdpartycode(){
Uri requestUri=uriInfo.getRequestUri();
//做点什么
}
}
@提供者
@生成(MediaType.WILDCARD)
公共类MyBodyWriter实现MessageBodyWriter{
@上下文
私人UriInfo UriInfo;
私人MyClass MyClass;
私人第三方课堂第三方课堂;
公共MyBodyWriter(){
myClass=新的myClass();
第三方类=新的第三方类();
第三方类注册表(myClass);
}
public void writeTo(最终MyView视图、最终类类型,/*等*/)抛出IOException、WebApplicationException{
myClass.setUriInfo(uriInfo);
//execute()调用MyClass#MethodCallebythirdPartyCode()
第三方类。execute();
myClass.setUriInfo(null);
}
}
我希望有更好的解决办法,但也许我完全走错了方向


谢谢!

迟来的回答,但这是一个好问题……所以我们走吧:

您可以使用
org.glassfish.hk2.api.Factory
javax.inject.Provider
进行注射。我不知道这是哪个版本,所以您可能需要升级jersery版本。对于以下示例,我使用了
jersey 2.12

首先,您必须为您的
MyClass
实现并注册/绑定工厂:

MyClassFactory:

import javax.inject.inject;
导入javax.ws.rs.core.UriInfo;
进口org.glassfish.hk2.api.Factory;
// ...
公共类MyClassFactory实现工厂{
私人最终UriInfo UriInfo;
//我们将在以后每次查找时绑定MyClassFactory,因此
//每次我们需要工厂时都会调用构造函数
//也就是说,uriInfo也是每次查找
@注入
公共MyClassFactory(最终UriInfo UriInfo){
this.uriInfo=uriInfo;
}
@凌驾
公共MyClass提供(){
返回新的MyClass(uriInfo)
}
@凌驾
公共无效处置(UriInfo UriInfo){
//忽略
}
}
通过ResourceConfig注册:

import org.glassfish.hk2.api.PerLookup;
导入org.glassfish.hk2.utilities.binding.AbstractBinder;
导入org.glassfish.jersey.server.ResourceConfig;
// ...
公共类MyResourceConfig扩展了ResourceConfig{
公共MyResourceConfig(){
注册(新的AbstractBinder(){
@凌驾
受保护的void configure(){
bindFactory(MyClassFactory.class).to(MyClass.class).in(PerLookup.class);
//…把更多的工厂绑在这里
}
});
// ...
}
}
现在,您可以将每次查找的MyClass注入到提供者、资源等中。
但请注意:Afaig有两种方法,只有一种方法最终适用于提供商

import javax.inject.inject;
导入javax.ws.rs.products;
导入javax.ws.rs.ext.MessageBodyWriter;
导入javax.ws.rs.ext.Provider;
// ...
@提供者
@产生(“应用程序/食物栏”)
公共类MyBodyWriter实现MessageBodyWriter{
//第一步-不要这样做!
//将只注入一次,因为MyBodyWriter只实例化一次
@注入
私人MyClass MyClass;
//第二种方法-效果很好!
私有最终javax.inject.Provider提供程序;
//MyBodyWriter实例化一次
//在这里获取注入提供程序
@注入
公共MyBodyWriter(javax.inject.Provider myClassProvider){
this.provider=myClassProvider;
}
@凌驾
公共布尔值是可写的(类t,类型g,注释[]a,媒体类型m){
返回t==MyView.class;
}
@凌驾
公共长getSize(MyView t,c类,类型g,注释[]a,媒体类型m){
//JAX-RS 2.0已弃用,Jersey运行时已忽略
返回0;
}
@凌驾
酒吧