关于不执行spring batch tasklet的执行方法的方法的AOP建议

时间:2018-05-25 07:27:53

标签: java spring hibernate spring-aop

此问题在从spring 4.1.2迁移到5.0.5,spring batch到3.0.9到4.0.1以及hibernate 4.2.0到5.2.16之后开始 我有一个格式的spring批处理tasklet -

public class MyTasklet implements Tasklet {
                    public RepeatStatus execute(StepContribution arg0, ChunkContext arg1) {
                        a();
                    }
                    public void a(){
                    //a few hibernate calls here
                    }
        }

现在我希望我的hibernate事务边界是方法a()[从execute调用]而不是execute()方法。 但是当我尝试使用切入点来实现同样的目标时,我收到了一条消息“没有正在进行的事务”。我在下面提供了样本xml。

在aop切入点 - 而不是方法名称'a'[ie public * myPackage.MyTasklet.a(..)],如果我使用*(即public * myPackage.MyTasklet.*(..)]或'执行'[ie {{1代码工作正常。由于某些技术原因,将边界设置为'a'非常重要,因为我不能将'执行'或任何其他方法作为边界。

public * myPackage.MyTasklet.execute(..)

1 个答案:

答案 0 :(得分:0)

这个问题在这里被问了好几百次。您的方法a()在内部调用,但内部方法调用永远不会被Spring AOP拦截,因为在这种情况下您实际调用this.a()。这不会通过Spring AOP使用的包装动态代理。如果从外部调用a(),e.e。通过另一个组件,它会工作。此行为在Spring AOP手册中为comprehensively documented

如果要拦截内部方法调用,则必须使用AspectJ而不是Spring AOP。如何为AspectJ and LTW (load-time weaving)配置Spring也在Spring手册中有记录。

P.S。:这与您的版本升级完全无关。在较早的Spring和Spring Batch版本中,它们将是相同的。您将重构(版本升级)与功能更改混合在一起,您绝不应该这样做。用于调试的移动目标太多。重构意味着在不改变其功能的情况下更改代码(或配置,在本例中)。