在 Jersey 2 + Spring 中使用 JSR-330 注释
Using JSR-330 annotations with Jersey 2 + Spring
我一直在尝试将 Spring 4 与 Jersey 2 一起使用,并注意到使用 jersey-spring3 扩展无法使 @Named
由 Spring 管理的注释资源。它们必须用 @Component
注释才能由 Spring 管理。
如果资源用 @Named
注释,HK2 似乎 "take over" 管理该资源。
资源
import com.example.jersey.spring.Greeting;
import java.util.logging.Logger;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
@Named
@Singleton
@Path("resource")
public class Resource {
private static final Logger logger = Logger.getLogger("Resource");
public void init() {
logger.info("Creating -> " + this + " injected with -> " + greeting);
}
@Inject
private Greeting greeting;
@GET
@Produces(MediaType.TEXT_PLAIN)
public String getIt() {
logger.info("Working on " + this + " Greeting " + greeting);
return "Got it!";
}
}
具有以下Spring applicationContext
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
default-init-method="init">
<context:component-scan base-package="com.example.jersey.webapp"/>
<bean id="greeting" class="com.example.jersey.spring.Greeting"/>
</beans>
导致在启动时打印以下日志消息
Oct 18, 2017 3:11:44 PM org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init>
INFO: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
Oct 18, 2017 3:11:44 PM com.example.jersey.webapp.Resource init
INFO: Creating -> com.example.jersey.webapp.Resource@6e199bab injected with -> com.example.jersey.spring.Greeting@533b3005
Oct 18, 2017 3:11:45 PM org.springframework.web.context.ContextLoader initWebApplicationContext
INFO: Root WebApplicationContext: initialization completed in 249 ms
在几次 GET 调用之后。
Oct 18, 2017 3:11:56 PM com.example.jersey.webapp.Resource getIt
INFO: Working on com.example.jersey.webapp.Resource@40328bbc Greeting com.example.jersey.spring.Greeting@533b3005
Oct 18, 2017 3:12:03 PM com.example.jersey.webapp.Resource getIt
INFO: Working on com.example.jersey.webapp.Resource@40328bbc Greeting com.example.jersey.spring.Greeting@533b3005
看来 Spring 确实创建了 bean,但那不是用于为请求提供服务的那个。但是,如果使用 Component
而不是 Named
,则整个生命周期由 Spring.
管理
有没有办法使用标准 @Named
注释并确保 Spring 完全管理资源的生命周期?
我认为没有办法禁用 HK2。
从最新的 Jersey-2 Userguide:
the resources must themselves be managed by Spring, by annotating with @Component, @Service, @Controller or @Repository
Spring 建议使用更具体的注释 @Service
、@Controller
和 @Repository
.
来自Spring 4.3.12 Documentation §7.10.1:
@Component and further stereotype annotations
The @Repository annotation is a marker for any class that fulfills the
role or stereotype of a repository (also known as Data Access Object
or DAO). Among the uses of this marker is the automatic translation of
exceptions as described in Section 20.2.2, “Exception translation”.
Spring provides further stereotype annotations: @Component, @Service,
and @Controller. @Component is a generic stereotype for any
Spring-managed component. @Repository, @Service, and @Controller are
specializations of @Component for more specific use cases, for
example, in the persistence, service, and presentation layers,
respectively. Therefore, you can annotate your component classes with
@Component, but by annotating them with @Repository, @Service, or
@Controller instead, your classes are more properly suited for
processing by tools or associating with aspects. For example, these
stereotype annotations make ideal targets for pointcuts. It is also
possible that @Repository, @Service, and @Controller may carry
additional semantics in future releases of the Spring Framework. Thus,
if you are choosing between using @Component or @Service for your
service layer, @Service is clearly the better choice. Similarly, as
stated above, @Repository is already supported as a marker for
automatic exception translation in your persistence layer.
我一直在尝试将 Spring 4 与 Jersey 2 一起使用,并注意到使用 jersey-spring3 扩展无法使 @Named
由 Spring 管理的注释资源。它们必须用 @Component
注释才能由 Spring 管理。
如果资源用 @Named
注释,HK2 似乎 "take over" 管理该资源。
资源
import com.example.jersey.spring.Greeting;
import java.util.logging.Logger;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
@Named
@Singleton
@Path("resource")
public class Resource {
private static final Logger logger = Logger.getLogger("Resource");
public void init() {
logger.info("Creating -> " + this + " injected with -> " + greeting);
}
@Inject
private Greeting greeting;
@GET
@Produces(MediaType.TEXT_PLAIN)
public String getIt() {
logger.info("Working on " + this + " Greeting " + greeting);
return "Got it!";
}
}
具有以下Spring applicationContext
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
default-init-method="init">
<context:component-scan base-package="com.example.jersey.webapp"/>
<bean id="greeting" class="com.example.jersey.spring.Greeting"/>
</beans>
导致在启动时打印以下日志消息
Oct 18, 2017 3:11:44 PM org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init>
INFO: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
Oct 18, 2017 3:11:44 PM com.example.jersey.webapp.Resource init
INFO: Creating -> com.example.jersey.webapp.Resource@6e199bab injected with -> com.example.jersey.spring.Greeting@533b3005
Oct 18, 2017 3:11:45 PM org.springframework.web.context.ContextLoader initWebApplicationContext
INFO: Root WebApplicationContext: initialization completed in 249 ms
在几次 GET 调用之后。
Oct 18, 2017 3:11:56 PM com.example.jersey.webapp.Resource getIt
INFO: Working on com.example.jersey.webapp.Resource@40328bbc Greeting com.example.jersey.spring.Greeting@533b3005
Oct 18, 2017 3:12:03 PM com.example.jersey.webapp.Resource getIt
INFO: Working on com.example.jersey.webapp.Resource@40328bbc Greeting com.example.jersey.spring.Greeting@533b3005
看来 Spring 确实创建了 bean,但那不是用于为请求提供服务的那个。但是,如果使用 Component
而不是 Named
,则整个生命周期由 Spring.
有没有办法使用标准 @Named
注释并确保 Spring 完全管理资源的生命周期?
我认为没有办法禁用 HK2。
从最新的 Jersey-2 Userguide:
the resources must themselves be managed by Spring, by annotating with @Component, @Service, @Controller or @Repository
Spring 建议使用更具体的注释 @Service
、@Controller
和 @Repository
.
来自Spring 4.3.12 Documentation §7.10.1:
@Component and further stereotype annotations
The @Repository annotation is a marker for any class that fulfills the role or stereotype of a repository (also known as Data Access Object or DAO). Among the uses of this marker is the automatic translation of exceptions as described in Section 20.2.2, “Exception translation”.
Spring provides further stereotype annotations: @Component, @Service, and @Controller. @Component is a generic stereotype for any Spring-managed component. @Repository, @Service, and @Controller are specializations of @Component for more specific use cases, for example, in the persistence, service, and presentation layers, respectively. Therefore, you can annotate your component classes with @Component, but by annotating them with @Repository, @Service, or @Controller instead, your classes are more properly suited for processing by tools or associating with aspects. For example, these stereotype annotations make ideal targets for pointcuts. It is also possible that @Repository, @Service, and @Controller may carry additional semantics in future releases of the Spring Framework. Thus, if you are choosing between using @Component or @Service for your service layer, @Service is clearly the better choice. Similarly, as stated above, @Repository is already supported as a marker for automatic exception translation in your persistence layer.