Spring AOP和泛型接口(继承)

时间:2012-03-29 23:19:57

标签: spring spring-aop

我已经查看过其他一些帖子,试图解决这个问题。

Clarification around Spring-AOP pointcuts and inheritance

Spring AOP pointcut that matches annotation on interface

我有一个场景,我们有一些基本接口定义了一些高级数据访问方法(通过泛型强类型)。然后我有一个接口实现了基本上覆盖/重新实现相同的方法,以便强类型化它们并提供JAX-WS注释。有趣的是,即使我重新定义了这个接口中的方法,Spring AOP切入点也不会接受切入点并启动一个Transaction ...所以我通过Spring / JPA / Hibernate得到一个错误“引起:javax.persistence。 TransactionRequiredException:没有正在进行的事务“。

我们有其他成功利用Spring AOP的“服务”,但它们不会从超级接口继承Generic方法。

这是顶级课程:

public interface BaseCoreDataService<O extends Comparable<O>, T extends DomainModel<O>> extends BaseService {

    @WebMethod(exclude = true)
    BaseDao<O, T> getBaseDao();

    O save(T model);

}

由此接口继承/扩展(添加另一种方法):

public interface BaseSimpleDataService<O extends Comparable<O>, T extends DomainModel<O>> extends
        BaseCoreDataService<O, T> {
    T get(O id);
}

最后继承/扩展了这个强类型Generic并提供JAX-WS注释的接口:

public interface UserDataService extends BaseSimpleDataService<Long, User> {

    @RequestWrapper(localName = "GetUserById", className = "com.foo.UserDataService.GetUserById", targetNamespace = "http://foo.com")
    @ResponseWrapper(localName = "GetUserByIdResponse", className = "com.foo.UserDataService.GetUserByIdResponse", targetNamespace = "http://foo.com")
    @WebResult(targetNamespace = "http://foo.com", name = "User")
    @WebMethod(operationName = "getUserById")
    User get(@WebParam(targetNamespace = "http://foo.com", name = "Id") Long id)
            throws ValidationException;

    @RequestWrapper(localName = "SaveUser", className = "com.foo.UserDataService.SaveUser", targetNamespace = "http://foo.com")
    @ResponseWrapper(localName = "SaveUserResponse", className = "com.foo.UserDataService.SaveUserResponse", targetNamespace = "http://foo.com")
    @WebResult(targetNamespace = "http://foo.com", name = "Id")
    @WebMethod(operationName = "saveUser")
    Long save(
            @WebParam(targetNamespace = "http://foo.com", name = "User") User model)
            throws ValidationException;
}

因此,如果我包含以下切入点,则调用会导致事务不存在的异常:

<bean id="GlobalDataTransactionManager" class="org.springframework.transaction.jta.WebLogicJtaTransactionManager"
    p:transactionManagerName="javax.transaction.TransactionManager"/>

<tx:advice id="GlobalDataTxAdvice" transaction-manager="GlobalDataTransactionManager">
    <tx:attributes>
        <tx:method name="get*" timeout="60" no-rollback-for="javax.persistence.NoResultException,javax.persistence.NonUniqueResultException,org.springframework.dao.EmptyResultDataAccessException"/>
        <tx:method name="find*" timeout="60" no-rollback-for="javax.persistence.NoResultException,javax.persistence.NonUniqueResultException,org.springframework.dao.EmptyResultDataAccessException"/>
        <tx:method name="search*" timeout="60" no-rollback-for="javax.persistence.NoResultException,javax.persistence.NonUniqueResultException,org.springframework.dao.EmptyResultDataAccessException"/>
        <tx:method name="*" timeout="60"/>
    </tx:attributes>
</tx:advice>

<aop:config>
    <aop:advisor advice-ref="GlobalDataTxAdvice" pointcut="execution(* com.foo..UserDataService.*(..))"/>
</aop:config>

但是,如果我为父类添加额外的顾问程序/切入点,则事务可以正常工作并且保存/获取基本上成功:

<aop:config>
    <aop:advisor advice-ref="GlobalDataTxAdvice" pointcut="execution(* com.foo..UserDataService.*(..))"/>
    <aop:advisor advice-ref="GlobalDataTxAdvice" pointcut="execution(* com.foo.core.*DataService.*(..))"/>
</aop:config>

我不确定问题是否围绕接口的继承?奇怪的是,在这个最终接口UserDataService中,我重新定义了所有方法......但是当使用“无事务正在进行”调用save / get时,这仍然失败,即使堆栈跟踪包含Spring AOP类。

所以添加额外的顾问/切入点修复它,我只想了解原因?

0 个答案:

没有答案