0

我一直在尝试将 Spring 4 与 Jersey 2 一起使用,并注意到使用 jersey-spring3 扩展无法使@NamedSpring 管理带注释的资源。它们必须带有注释@Component才能由 Spring 管理。

如果使用@NamedHK2 注释资源似乎“接管”管理该资源。

资源

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,但它不是用于为请求提供服务的那个。但是,如果使用 , 而不是Named,Component则整个生命周期都由 Spring 管理。

有没有办法使用标准@Named注释并确保 Spring 完全管理资源的生命周期?

4

1 回答 1

0

我认为没有办法禁用 HK2。

来自最新的 Jersey-2 用户指南

资源本身必须由 Spring 管理,通过使用 @Component、@Service、@Controller 或 @Repository 进行注释

Spring 建议使用更具体的注解@Service@Controller并且@Repository.

Spring 4.3.12 文档 §7.10.1

@Component 和进一步的原型注解

@Repository 注释是任何满足存储库角色或原型的类的标记(也称为数据访问对象或 DAO)。此标记的用途之一是异常的自动翻译,如第 20.2.2 节“异常翻译”中所述。

Spring 提供了更多的原型注解:@Component、@Service 和@Controller。@Component 是任何 Spring 管理的组件的通用构造型。@Repository、@Service 和 @Controller 是 @Component 针对更具体的用例的特化,例如,分别在持久层、服务层和表示层中。因此,您可以使用@Component 注释您的组件类,但是通过使用@Repository、@Service 或@Controller 来注释它们,您的类更适合工具处理或与方面关联。例如,这些原型注释是切入点的理想目标。在 Spring Framework 的未来版本中,@Repository、@Service 和 @Controller 也可能带有额外的语义。因此,如果您在使用@Component 或@Service 作为服务层进行选择,@Service 显然是更好的选择。同样,如上所述,@Repository 已被支持作为持久层中自动异常转换的标记。

于 2017-10-26T09:26:11.493 回答