简体   繁体   English

AOP关于除弹簧批处理小任务的执行方法以外的方法的建议未得到应用

[英]AOP advice on methods other than execute method of spring batch tasklet not being applied

This issue has started after migrating from spring 4.1.2 to 5.0.5, spring batch to 3.0.9 to 4.0.1 and hibernate 4.2.0 to 5.2.16 I have a spring batch tasklet of the format - 从Spring 4.1.2迁移到5.0.5,从Spring Batch迁移到3.0.9到4.0.1,从Hibernate 4.2.0迁移到5.2.16之后,这个问题就开始了。

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

Now I want my hibernate transaction boundary to be the method a() [being called from execute] and not the execute() method. 现在,我希望我的休眠事务边界是方法a()[从execute中调用],而不是execute()方法。 But when I try applying point-cuts to achieve the same I get a message "no transaction in progress" . 但是,当我尝试应用切入点来实现相同的目的时,会收到一条消息“没有正在进行的交易” I have provided the sample xml below. 我在下面提供了示例XML。

In the aop pointcut -instead of the method name 'a'[ie public * myPackage.MyTasklet.a(..) ], if I use * (ie public * myPackage.MyTasklet.*(..) ] or 'execute'[ie public * myPackage.MyTasklet.execute(..) ] the code works fine. Due to some technical reasons it is important to have the boundary at 'a' due to which I cannot have 'execute' or any other method as the boundary. 在aop切入点中,而不是方法名'a'[ie public * myPackage.MyTasklet.a(..) ],如果我使用* (即public * myPackage.MyTasklet.*(..) ]或'execute' [即public * myPackage.MyTasklet.execute(..) ]的代码工作正常。由于一些技术原因而必须在“A”由于我不能有“执行”的边界或任何其他方法作为重要的是边界。


<tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="*" propagation="REQUIRED" />
        </tx:attributes>
</tx:advice>

<bean id="transactionManager"
        class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory" ref="mySessionFactory" />
</bean>
<aop:config>
        <aop:pointcut id="Op1"
            expression="execution(public * myPackage.MyTasklet.a(..))" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="Op1" />
</aop:config>

This question has been asked hundreds of times here. 这个问题在这里已经被问过数百遍了。 Your method a() is called internally, but internal method calls are never intercepted by Spring AOP because in that case you actually call this.a() . 您的方法a()在内部被调用,但是内部方法调用永远不会被Spring AOP拦截,因为在这种情况下,您实际上是在调用this.a() This does not go through the wrapping dynamic proxy used by Spring AOP. 这不会通过Spring AOP使用的包装动态代理。 If a() was called from outside, ee by another component, it would work. 如果a()是由另一个组件从外部ee调用的,则它将起作用。 This behaviour is comprehensively documented in the Spring AOP manual. Spring AOP手册中全面记录了此行为。

If you want to intercept internal method calls you have to use AspectJ instead of Spring AOP. 如果要拦截内部方法调用,则必须使用AspectJ而不是Spring AOP。 How to configure Spring for AspectJ and LTW (load-time weaving) is also documented in the Spring manual. Spring手册中还介绍了如何为AspectJ和LTW(加载时编织)配置Spring。

PS: This is completely unrelated to your version upgrades. PS:这与您的版本升级完全无关。 In older Spring and Spring Batch versions it would be the same. 在较旧的Spring和Spring Batch版本中,它是相同的。 You mixed refactoring (version upgrade) with functional changes , which you should never do. 您将重构 (版本升级)与功能更改混合在一起,这是您永远都不应做的。 Too many moving targets for debugging. 用于调试的移动目标太多。 Refactoring means to change the code (or the configuration, in this case) without changing its functionality. 重构意味着在不更改其功能的情况下更改代码(或本示例中的配置)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM