首页 > 解决方案 > 在抽象类和子方法之间使用 Spring 事务代理

问题描述

我有一个抽象的基础服务和两个实现:

public abstract class AbstractBaseService {
  public void mainProcess() {
    for (Foo foo : getFoos()) {
      doSomething(foo);
    }
  }
  abstract List<Foo> getFoos();
  abstract void doSomething(Foo foo);
}

public class ServiceImplOne extends AbstractBaseService {
  protected List<Foo> getFoos() { ... }
  protected void doSomething(Foo foo) { ... }
}

public class ServiceImplTwo extends AbstractBaseService { ... }

如果出现问题doSomething(foo),我想回滚对该对象所做的任何更改,将错误写入日志文件,然后继续列表中的下一个对象。所以,我将在我的基础服务的循环内添加一个 try-catch ......并使用实现类中@Transactional的方法进行注释。doSomething但根据Spring 的文档

当您使用代理时,您应该@Transactional只将注释应用于具有公共可见性的方法。如果您使用注解对受保护的、私有的或包可见的方法进行@Transactional注解,则不会引发错误,但被注解的方法不会显示配置的事务设置。如果您需要注释非公共方法,请考虑使用 AspectJ(稍后介绍)。

我的方法是protected......我可以将可见性更改为public,但也存在以下问题:

处理@Transactional注解的默认通知模式是proxy,它只允许通过代理拦截调用。同一类中的本地调用不能以这种方式被拦截。对于更高级的拦截模式,请考虑切换到aspectj结合编译时或加载时编织的模式。

因此,代理将无法拦截来自同一类的调用。这是否也适用于抽象类与其实现之间的调用,还是会按我的意图工作?有什么简单的方法可以自己检查吗?(可能是一个愚蠢的问题,当谈到 Java 代理时我有点迷茫......)

我一直在寻找一段时间,但我只设法找到这两个 问题,他们专注于@Transactional标签本身的继承......在这种情况下这并不重要,我不在乎注释所有doSomething实现,而不仅仅是抽象方法。

标签: javaspringspring-aopspring-transactions

解决方案


的实例ServiceImplOne是 的实例AbstractBaseService。当您创建ServiceImplOne. 它的mainProcess()方法调用它的doSomething()方法。

该调用不是从一个 Spring bean 到另一个 Spring bean 的调用,因此没有什么可以被拦截的。


推荐阅读