@Context对象来自哪里

时间:2020-12-11 11:34:01

I've been searching everywhere, but can't seem to find a clear answer...

我到处找遍了,但似乎找不到一个明确的答案……

What is the mechanism whereby a server (glassfish for my problem) injects actual objets that are annotated with @Context? More specifically, if I wanted to write a class that did something like:

服务器(针对我的问题,是glassfish)通过什么机制注入带有@Context注释的实际objets ?更具体地说,如果我想写一个类似于:

@Path("/")
public class MyResource {
  @GET
  public String doSomething(@Context MyObject obj) {
    // ...
  }
}

then how would I do it? Where is it that the MyObject is instanciated, who does it, and how?

那我该怎么做呢?在哪里,MyObject是instanciated,谁做的,如何?

Edit: I've seen stuff like the following:

编辑:我看到过以下内容:

Using @Context, @Provider and ContextResolver in JAX-RS

在JAX-RS中使用@Context、@Provider和上下文解析器

http://jersey.576304.n2.nabble.com/ContextResolver-confusion-td5654154.html

http://jersey.576304.n2.nabble.com/ContextResolver-confusion-td5654154.html

However, this doesn't square with what I've seen, e.g. in the constructor of org.neo4j.server.rest.web.RestfulGraphDatabase, which has the following signature:

然而,这与我所看到的并不一致,例如,在org.neo4j.server.rest.web的构造函数中。RestfulGraphDatabase,它具有以下签名:

public RestfulGraphDatabase(
  @Context UriInfo uriInfo,
  @Context Database database,
  @Context InputFormat input,
  @Context OutputFormat output,
  @Context LeaseManager leaseManager )

4 个解决方案

#1


7  

You can write your own injection provider and plug that into Jersey - look at SingletonTypeInjectableProvider and PerRequestTypeInjectableProvider - extend one of these classes (depending on the lifecycle you want for the injectable object) and register your implementation as a provider in your web app.

您可以编写您自己的注入提供程序并将其插入Jersey——查看SingletonTypeInjectableProvider和PerRequestTypeInjectableProvider——扩展其中的一个类(取决于您想要注入对象的生命周期),并将实现注册为web应用程序中的提供者。

For example, something like this:

例如:

@Provider
public class MyObjectProvider extends SingletonTypeInjectableProvider<Context, MyObject> {
    public MyObjectProvider() {
        // binds MyObject.class to a single MyObject instance
        // i.e. the instance of MyObject created bellow will be injected if you use
        // @Context MyObject myObject
        super(MyObject.class, new MyObject());
    }
}

To include the provider in your web app you have several options:

要将提供者包含在web应用程序中,您有以下几个选项:

  1. if your app uses classpath scanning (or package scanning) just make sure the provider is in the right package / on the classpath
  2. 如果您的应用程序使用类路径扫描(或包扫描),请确保提供程序位于类路径中的正确的包/包中
  3. or you can simply register it using META-INF/services entry (add META-INF/services/com.sun.jersey.spi.inject.InjectableProvider file having the name of your provider class in it's contents)
  4. 或者您可以使用META-INF/services条目注册它(添加META-INF/services/ com.sun.jersey.spi.spi.inject)。注入表提供程序文件的内容中包含您的提供程序类的名称)

#2


3  

I think I may be on to something...and if this works, Martin should get partial credit. :)

我想我可能明白了……如果这行得通,马丁应该得到部分学分。:)

It appears that the @Provider class must implement the com.sun.jersey.spi.inject.Injectable<T> interface. However, I'm not sure that this is enough to actually have the @Context be injected. What's missing, is that we have to tell the ResourceConfig object of the web app about the @Provider. In the context of what I'm trying to do, and taking hints from neo4j-server, the remaining work boils down to:

似乎@Provider类必须实现com.sun.jersey.spi.inject。注射< T >界面。然而,我不确定这是否足以注入@Context。缺少的是,我们必须告诉web应用程序的ResourceConfig对象关于@Provider。在我正在尝试做的事情以及从neo4j-server中得到提示的背景下,剩下的工作归结为:

  • extending com.sun.jersey.spi.container.servlet.ServletContainer, and overriding the configure method:
  • 延长com.sun.jersey.spi.container.servlet。伺服容器,并覆盖配置方法:
@Override
protected void configure(WebConfig wc, ResourceConfig rc, WebApplication wa)
{
  super.configure( wc, rc, wa );
  Set<Object> singletons = rc.getSingletons();
  singletons.add(new MyObjectProvider());
}
  • specifying that this container must be used in the web.xml deployment descriptor:
  • 指定这个容器必须在web中使用。xml部署描述符:
<servlet>
  <servlet-name>JAX-RS Servlet Container</servlet-name>
  <servlet-class>com.blah.MyServletContainer</servlet-class>
</servlet>

#3


0  

I don't think you can use @Context with a user-defined type like MyObject. It is for injecting types that jax-ws already understands. It is mentioned here.

我认为您不能使用像MyObject这样的用户定义类型使用@Context。它用于注入jax-ws已经理解的类型。这里提到的。

Chapter 5 of the JAX-RS specification presents all the standard JAX-RS Java types that may be used with @Context.

JAX-RS规范的第5章介绍了所有标准的JAX-RS Java类型,这些Java类型可以与@Context一起使用。

You probably want to use something like @FormParam or @PathParam instead. See section 2.3 of the spec for a description. Here is your answer, copied from that section of the spec:

您可能希望使用类似于@FormParam或@PathParam的东西。有关说明,请参见规范的第2.3节。这是你的答案,是从说明书的那部分拷贝过来的:

In general the Java type of the method parameter may:

一般来说,Java类型的方法参数可以:

  1. Be a primitive type;
  2. 是一个原始类型;
  3. Have a constructor that accepts a single String argument;
  4. 拥有一个接受单个字符串参数的构造函数;
  5. Have a static method named valueOf or fromString that accepts a single String argument (see, for example, Integer.valueOf(String) and java.util.UUID.fromString(String)); or
  6. 有一个名为valueOf或fromString的静态方法,它接受单个字符串参数(例如,Integer.valueOf(String)和java.util. uid .fromString(String));或
  7. Be List, Set or SortedSet, where T satisfies 2 or 3 above. The resulting collection is read-only.
  8. 为List, Set或SortedSet,其中T满足2或3以上。结果的集合是只读的。

#4


-1  

See chapters 5-6 of the JAX-RS spec. That should tell you everything you need to know about it.

请参阅JAX-RS规范的第5-6章,这将告诉您关于它所需的所有信息。

#1


7  

You can write your own injection provider and plug that into Jersey - look at SingletonTypeInjectableProvider and PerRequestTypeInjectableProvider - extend one of these classes (depending on the lifecycle you want for the injectable object) and register your implementation as a provider in your web app.

您可以编写您自己的注入提供程序并将其插入Jersey——查看SingletonTypeInjectableProvider和PerRequestTypeInjectableProvider——扩展其中的一个类(取决于您想要注入对象的生命周期),并将实现注册为web应用程序中的提供者。

For example, something like this:

例如:

@Provider
public class MyObjectProvider extends SingletonTypeInjectableProvider<Context, MyObject> {
    public MyObjectProvider() {
        // binds MyObject.class to a single MyObject instance
        // i.e. the instance of MyObject created bellow will be injected if you use
        // @Context MyObject myObject
        super(MyObject.class, new MyObject());
    }
}

To include the provider in your web app you have several options:

要将提供者包含在web应用程序中,您有以下几个选项:

  1. if your app uses classpath scanning (or package scanning) just make sure the provider is in the right package / on the classpath
  2. 如果您的应用程序使用类路径扫描(或包扫描),请确保提供程序位于类路径中的正确的包/包中
  3. or you can simply register it using META-INF/services entry (add META-INF/services/com.sun.jersey.spi.inject.InjectableProvider file having the name of your provider class in it's contents)
  4. 或者您可以使用META-INF/services条目注册它(添加META-INF/services/ com.sun.jersey.spi.spi.inject)。注入表提供程序文件的内容中包含您的提供程序类的名称)

#2


3  

I think I may be on to something...and if this works, Martin should get partial credit. :)

我想我可能明白了……如果这行得通,马丁应该得到部分学分。:)

It appears that the @Provider class must implement the com.sun.jersey.spi.inject.Injectable<T> interface. However, I'm not sure that this is enough to actually have the @Context be injected. What's missing, is that we have to tell the ResourceConfig object of the web app about the @Provider. In the context of what I'm trying to do, and taking hints from neo4j-server, the remaining work boils down to:

似乎@Provider类必须实现com.sun.jersey.spi.inject。注射< T >界面。然而,我不确定这是否足以注入@Context。缺少的是,我们必须告诉web应用程序的ResourceConfig对象关于@Provider。在我正在尝试做的事情以及从neo4j-server中得到提示的背景下,剩下的工作归结为:

  • extending com.sun.jersey.spi.container.servlet.ServletContainer, and overriding the configure method:
  • 延长com.sun.jersey.spi.container.servlet。伺服容器,并覆盖配置方法:
@Override
protected void configure(WebConfig wc, ResourceConfig rc, WebApplication wa)
{
  super.configure( wc, rc, wa );
  Set<Object> singletons = rc.getSingletons();
  singletons.add(new MyObjectProvider());
}
  • specifying that this container must be used in the web.xml deployment descriptor:
  • 指定这个容器必须在web中使用。xml部署描述符:
<servlet>
  <servlet-name>JAX-RS Servlet Container</servlet-name>
  <servlet-class>com.blah.MyServletContainer</servlet-class>
</servlet>

#3


0  

I don't think you can use @Context with a user-defined type like MyObject. It is for injecting types that jax-ws already understands. It is mentioned here.

我认为您不能使用像MyObject这样的用户定义类型使用@Context。它用于注入jax-ws已经理解的类型。这里提到的。

Chapter 5 of the JAX-RS specification presents all the standard JAX-RS Java types that may be used with @Context.

JAX-RS规范的第5章介绍了所有标准的JAX-RS Java类型,这些Java类型可以与@Context一起使用。

You probably want to use something like @FormParam or @PathParam instead. See section 2.3 of the spec for a description. Here is your answer, copied from that section of the spec:

您可能希望使用类似于@FormParam或@PathParam的东西。有关说明,请参见规范的第2.3节。这是你的答案,是从说明书的那部分拷贝过来的:

In general the Java type of the method parameter may:

一般来说,Java类型的方法参数可以:

  1. Be a primitive type;
  2. 是一个原始类型;
  3. Have a constructor that accepts a single String argument;
  4. 拥有一个接受单个字符串参数的构造函数;
  5. Have a static method named valueOf or fromString that accepts a single String argument (see, for example, Integer.valueOf(String) and java.util.UUID.fromString(String)); or
  6. 有一个名为valueOf或fromString的静态方法,它接受单个字符串参数(例如,Integer.valueOf(String)和java.util. uid .fromString(String));或
  7. Be List, Set or SortedSet, where T satisfies 2 or 3 above. The resulting collection is read-only.
  8. 为List, Set或SortedSet,其中T满足2或3以上。结果的集合是只读的。

#4


-1  

See chapters 5-6 of the JAX-RS spec. That should tell you everything you need to know about it.

请参阅JAX-RS规范的第5-6章,这将告诉您关于它所需的所有信息。