将请求范围的上下文字段注入到 RESTEasy 单例中
Request-scoped context field injections into RESTEasy singletons
当尝试在 OSGi 中嵌入带有单例资源的 RESTEasy(使用类似于 resteasy-osgi-bundle 的东西)时,令我惊讶的是,字段注入 @Context
UriInfo
在每个请求上都可用且有效.
深入挖掘后,我在 ResteasyProviderFactory
中发现了代理魔法和 ThreadLocal
。一切都很好,但我在文档中找不到任何关于这种行为的参考,无论是在 RESTEasy 的文档中还是在 JAX-RS 规范中。
在Jersey docs中我们可以找到类似的东西:
The exception exists for specific request objects which can injected even into constructor or class fields [of resources with singleton scope — OP]. For these objects the runtime will inject proxies which are able to simultaneously server more request. These request objects are HttpHeaders
, Request
, UriInfo
, SecurityContext
. These proxies can be injected using the @Context
annotation.
它在 RESTEasy 中的表现如何?当前的实施是稳定的还是实验性的?可以注入到单例中的特定请求集 类 是什么?
这不是实验性的。此行为(对于一组公共对象)在 JAX-RS spec 中指定。规范页面中没有指向特定部分的 link 的任何锚点,但您应该查看的是 第 5 章:上下文 。我会 post 一些片段在这里。
5.1 Concurrency
Context is specific to a particular request but instances of certain JAX-RS components (providers and resource classes with a lifecycle other than per-request) may need to support multiple concurrent requests. When injecting an instance of one of the types listed in section 5.2, the instance supplied MUST be capable of selecting the correct context for a particular request. Use of a thread-local proxy is a common way to achieve this.
5.2 Context Types
This section describes the types of context available to resource classes, providers and Application
subclasses.
5.2.1 Application
The instance of the application-supplied Application
subclass can be injected into a class field or method parameter using the @Context
annotation. Access to the Application subclass instance allows configuration information to be centralized in that class. Note that this cannot be injected into the Application subclass itself since this would create a circular dependency.
5.2.2 URIs and URI Templates
An instance of UriInfo
can be injected into a class field or method parameter using the @Context
annotation. UriInfo provides both static and dynamic, per-request information, about the components of a request URI. E.g. the following would return the names of any query parameters in a request:
5.2.3 Headers
An instance of HttpHeaders
can be injected into a class field or method parameter using the @Context
annotation. HttpHeaders
provides access to request header information either in map form or via strongly typed convenience methods. E.g. the following would return the names of all the headers in a request:
5.2.4 Content Negotiation and Preconditions
JAX-RS simplifies support for content negotiation and preconditions using the Request
interface. An instance of Request
can be injected into a class field or method parameter using the @Context
annotation. The methods of Request
allow a caller to determine the best matching representation variant and to evaluate whether the current state of the resource matches any preconditions in the request...
5.2.5 Security Context
The SecurityContext
interface provides access to information about the security context of the current request. An instance of SecurityContext
can be injected into a class field or method parameter using the @Context
annotation. The methods of SecurityContext
provide access to the current user principal, information about roles assumed by the requester, whether the request arrived over a secure channel and the authentication scheme used.
5.2.6 Providers
The Providers
interface allows for lookup of provider instances based on a set of search criteria. An instance of Providers
can be injected into a class field or method parameter using the @Context
annotation.
需要注意的一件事是,可以注入的类型可能更多,但上面未列出的任何类型都是特定于实现的。这是 Chapter 15. @Context
部分中 RESTeasy 文档的列表
The @Context
annotation allows you to inject instances of javax.ws.rs.core.HttpHeaders
, javax.ws.rs.core.UriInfo
, javax.ws.rs.core.Request
, javax.servlet.HttpServletRequest
, javax.servlet.HttpServletResponse
, javax.servlet.ServletConfig
, javax.servlet.ServletContext
, and javax.ws.rs.core.SecurityContext
objects.
虽然文档没有区分字段和参数注入,但根据我的记忆,我认为我能够将 HttpServletRequest
注入到字段中。但我会测试它们以确保。
当尝试在 OSGi 中嵌入带有单例资源的 RESTEasy(使用类似于 resteasy-osgi-bundle 的东西)时,令我惊讶的是,字段注入 @Context
UriInfo
在每个请求上都可用且有效.
深入挖掘后,我在 ResteasyProviderFactory
中发现了代理魔法和 ThreadLocal
。一切都很好,但我在文档中找不到任何关于这种行为的参考,无论是在 RESTEasy 的文档中还是在 JAX-RS 规范中。
在Jersey docs中我们可以找到类似的东西:
The exception exists for specific request objects which can injected even into constructor or class fields [of resources with singleton scope — OP]. For these objects the runtime will inject proxies which are able to simultaneously server more request. These request objects are
HttpHeaders
,Request
,UriInfo
,SecurityContext
. These proxies can be injected using the@Context
annotation.
它在 RESTEasy 中的表现如何?当前的实施是稳定的还是实验性的?可以注入到单例中的特定请求集 类 是什么?
这不是实验性的。此行为(对于一组公共对象)在 JAX-RS spec 中指定。规范页面中没有指向特定部分的 link 的任何锚点,但您应该查看的是 第 5 章:上下文 。我会 post 一些片段在这里。
5.1 Concurrency
Context is specific to a particular request but instances of certain JAX-RS components (providers and resource classes with a lifecycle other than per-request) may need to support multiple concurrent requests. When injecting an instance of one of the types listed in section 5.2, the instance supplied MUST be capable of selecting the correct context for a particular request. Use of a thread-local proxy is a common way to achieve this.
5.2 Context Types
This section describes the types of context available to resource classes, providers and
Application
subclasses.5.2.1 Application
The instance of the application-supplied
Application
subclass can be injected into a class field or method parameter using the@Context
annotation. Access to the Application subclass instance allows configuration information to be centralized in that class. Note that this cannot be injected into the Application subclass itself since this would create a circular dependency.5.2.2 URIs and URI Templates
An instance of
UriInfo
can be injected into a class field or method parameter using the@Context
annotation. UriInfo provides both static and dynamic, per-request information, about the components of a request URI. E.g. the following would return the names of any query parameters in a request:5.2.3 Headers
An instance of
HttpHeaders
can be injected into a class field or method parameter using the@Context
annotation.HttpHeaders
provides access to request header information either in map form or via strongly typed convenience methods. E.g. the following would return the names of all the headers in a request:5.2.4 Content Negotiation and Preconditions
JAX-RS simplifies support for content negotiation and preconditions using the
Request
interface. An instance ofRequest
can be injected into a class field or method parameter using the@Context
annotation. The methods ofRequest
allow a caller to determine the best matching representation variant and to evaluate whether the current state of the resource matches any preconditions in the request...5.2.5 Security Context
The
SecurityContext
interface provides access to information about the security context of the current request. An instance ofSecurityContext
can be injected into a class field or method parameter using the@Context
annotation. The methods ofSecurityContext
provide access to the current user principal, information about roles assumed by the requester, whether the request arrived over a secure channel and the authentication scheme used.5.2.6 Providers
The
Providers
interface allows for lookup of provider instances based on a set of search criteria. An instance ofProviders
can be injected into a class field or method parameter using the@Context
annotation.
需要注意的一件事是,可以注入的类型可能更多,但上面未列出的任何类型都是特定于实现的。这是 Chapter 15. @Context
部分中 RESTeasy 文档的列表The
@Context
annotation allows you to inject instances ofjavax.ws.rs.core.HttpHeaders
,javax.ws.rs.core.UriInfo
,javax.ws.rs.core.Request
,javax.servlet.HttpServletRequest
,javax.servlet.HttpServletResponse
,javax.servlet.ServletConfig
,javax.servlet.ServletContext
, andjavax.ws.rs.core.SecurityContext
objects.
虽然文档没有区分字段和参数注入,但根据我的记忆,我认为我能够将 HttpServletRequest
注入到字段中。但我会测试它们以确保。