Java 如何让jersey web服务类实现接口和事务性

Java 如何让jersey web服务类实现接口和事务性,java,jersey,spring-transactions,Java,Jersey,Spring Transactions,我想使用Jersey和Spring编写一个java类,它既是web服务服务器端类,也是SpringTX的事务类(这样每个web服务请求要么完全完成其在db中的工作,要么完全回滚其在db中的工作) 但是,当我这样做的时候 package com.test.rest import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; @C

我想使用Jersey和Spring编写一个java类,它既是web服务服务器端类,也是SpringTX的事务类(这样每个web服务请求要么完全完成其在db中的工作,要么完全回滚其在db中的工作)

但是,当我这样做的时候

package com.test.rest

import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

@Component 
@Transactional
public class TestRestService implements TestRestServiceInterface {
    ...
}
Spring没有将TestRestService类注册为web服务类

我在spring配置文件中使用
在com.test.rest包中注册web服务类(示例中更改了包名)

如果我删除@Transactional或者让TestRestService没有实现接口,那么Spring会将该类注册为一个web服务类,并且代码可以正常工作

有没有办法让我两者兼得


我目前正在使用sprint tx、spring jersey和spring context 3.0.7以及jersey 1.0.3.1,在看了很多之后,我得出了这样的结论:如果没有AspectJ,它将无法工作

我相信它不会工作,因为jersey-server-1.0.3.1:com.sun.jersey.api.core.ResourceConfig.java中的代码

438  /**
439   * Determine if a class is a root resource class.
440   *
441   * @param c the class.
442   * @return true if the class is a root resource class, otherwise false
443   *         (including if the class is null).
444   */
445  public static boolean isRootResourceClass(Class<?> c) {
446      if (c == null)
447          return false;
448      
449      if (c.isAnnotationPresent(Path.class)) return true;
450  
451      for (Class i : c.getInterfaces())
452          if (i.isAnnotationPresent(Path.class)) return true;
453  
454      return false;
455  }
438/**
439*确定类是否为根资源类。
440   *
441*@param c类。
442*@如果类是根资源类,则返回true,否则返回false
443*(包括类为空时)。
444   */
445公共静态布尔isRootResourceClass(c类){
446如果(c==null)
447返回错误;
448
449 if(c.isAnnotationPresent(Path.class))返回true;
450
451(i类:c.getInterfaces())
452如果(i.isAnnotationPresent(Path.class))返回true;
453
454返回错误;
455  }
出于某种原因,当我们在实现接口的类上有@Transactional时,spring tx生成的代理类(无论是基于CGLIB还是基于JDK动态代理)没有@Path注释,因此isRootResourceClass返回false,并且该类未注册为web服务类。我在调试代码时验证了这一点


我想我将不得不在实现接口或使我的web服务类具有事务性(除非我使用AspectJ)之间做出选择。

在看了很多之后,我得出结论,它将无法工作(也许没有AspectJ)

我相信它不会工作,因为jersey-server-1.0.3.1:com.sun.jersey.api.core.ResourceConfig.java中的代码

438  /**
439   * Determine if a class is a root resource class.
440   *
441   * @param c the class.
442   * @return true if the class is a root resource class, otherwise false
443   *         (including if the class is null).
444   */
445  public static boolean isRootResourceClass(Class<?> c) {
446      if (c == null)
447          return false;
448      
449      if (c.isAnnotationPresent(Path.class)) return true;
450  
451      for (Class i : c.getInterfaces())
452          if (i.isAnnotationPresent(Path.class)) return true;
453  
454      return false;
455  }
438/**
439*确定类是否为根资源类。
440   *
441*@param c类。
442*@如果类是根资源类,则返回true,否则返回false
443*(包括类为空时)。
444   */
445公共静态布尔isRootResourceClass(c类){
446如果(c==null)
447返回错误;
448
449 if(c.isAnnotationPresent(Path.class))返回true;
450
451(i类:c.getInterfaces())
452如果(i.isAnnotationPresent(Path.class))返回true;
453
454返回错误;
455  }
出于某种原因,当我们在实现接口的类上有@Transactional时,spring tx生成的代理类(无论是基于CGLIB还是基于JDK动态代理)没有@Path注释,因此isRootResourceClass返回false,并且该类未注册为web服务类。我在调试代码时验证了这一点


我想我必须在实现一个接口或使我的web服务类成为事务性的(除非我使用AspectJ)之间做出选择。

如果删除该接口并使用CGLIB代理怎么办?在Spring中添加CGLIB并启用基于类的代理。感谢Tomasz,但如果可能的话,我们希望保留该接口,即使没有它,默认的JDK动态代理也可以正常工作。理想情况下,我们希望接口和类是事务性的。更正,我从文档和Tomasz自己关于SpringAOP陷阱的文章中发现,没有接口JDK代理无法工作。我想知道是否可以使用带有接口的CGLIB代理。我要试试。我把
改为
,问题仍然存在。我想这是不应该的。如果您删除该接口并使用CGLIB代理怎么办?在Spring中添加CGLIB并启用基于类的代理。感谢Tomasz,但如果可能的话,我们希望保留该接口,即使没有它,默认的JDK动态代理也可以正常工作。理想情况下,我们希望接口和类是事务性的。更正,我从文档和Tomasz自己关于SpringAOP陷阱的文章中发现,没有接口JDK代理无法工作。我想知道是否可以使用带有接口的CGLIB代理。我要试试。我把
改为
,问题仍然存在。我想这不是命中注定的。你能解决这个问题吗?我有一个类似的问题,我的基于jersey的rest服务类在某些方法上有@Transactional注释(PUT)。但是当我从rest服务客户机调用服务方法时,它给了我一个空指针异常(对于@autowired DAO)。如果我从方法中删除@Transactional,那么它不会抛出空指针,但也不会提交事务。我还尝试了使用AOP from XML,得到了相同的结果。它似乎无法处理事务性方法。我的应用程序是基于Spring3.1、JPA和Jersey 1.17的,我已经解决了。当您将事务性服务与jersey资源分离时,它会起作用。这意味着,您不必在事务服务类中使用jersey注释,而是创建一个新类,该类作为jersey资源公开。然后,此新泽西资源可以使用事务服务类(通过spring注入)来持久化对象。您能够解决此问题吗?我有一个类似的问题,基于jersey的rest服务类在某些方法上有@Transactional注释