在Jersey 2 + Spring中使用JSR-330注释

时间:2017-10-18 09:58:57

标签: jersey-2.0 spring-jersey

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

如果资源注释为@Named HK2似乎“接管”管理该资源。

资源

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,但这不是用于服务请求的bean。但是,如果使用Named代替Component,则整个生命周期由Spring管理。

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

1 个答案:

答案 0 :(得分:0)

我不认为有办法禁用HK2。

来自最新的Jersey-2 Userguide

  

资源必须由Spring管理,通过@Component,@ Service,@ Controller或@Repository注释

Spring建议使用更具体的注释@Service@Controller@Repository

来自Spring 4.3.12 Documentation §7.10.1

  

@Component和进一步的刻板印注

     

@Repository注释是任何满足该类的类的标记   存储库的角色或构造型(也称为数据访问对象)   或DAO)。这个标记的用途之一是自动翻译   第20.2.2节“异常翻译”中描述的例外情况。

     

Spring提供了进一步的构造型注释:@Component,@ Service,   和@Controller。 @Component是任何的通用构造型   Spring管理的组件。 @ Repository,@ Service和@Controller都是   对于更具体的用例,@ Component的特化   例如,在持久性,服务和表示层中,   分别。因此,您可以使用注释组件类   @Component,但是用@ Repository,@ Service或者注释它们   相反,@ Controller更适合你的类   通过工具处理或与方面相关联。例如,这些   构造型注释成为切入点的理想目标。也是   @Repository,@ Service和@Controller可能会携带   Spring框架的未来版本中的其他语义。从而,   如果您选择使用@Component或@Service作为您的   服务层,@ Service显然是更好的选择。同样,如   如上所述,已经支持@Repository作为标记   持久层中的自动异常转换。