自定义Spring AOP周围+ @Transactional [英] Custom Spring AOP Around + @Transactional

查看:102
本文介绍了自定义Spring AOP周围+ @Transactional的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我实现了一个自定义的周围"以匹配自定义的注释".我希望周围的自定义可以在外部@Transactional中执行.不幸的是,这似乎不起作用. (AOP正在运行.我看到了显示它的堆栈跟踪).

I have a custom Around implemented to match on a custom Annotation. I want the custom around to execute WITHIN the outer @Transactional. Unfortunately, this doesn't appear to work. (The AOP is working. I see stacktraces that show it).

堆栈跟踪显示我的AOP在(记录器)之前执行,MyBatis会话开始事务,MyBatis关闭事务,Spring关闭事务,然后我的AOP完成.

The stack traces show my AOP executing before (a logger), the MyBatis Session starting a transaction, MyBatis closing the Transactions, Spring closing the transaction and then my AOP completing.

我认为订购AOP实施程序会有所帮助.我将返回的值设置为1.这没用.我认为是因为我误读了Spring的订单.

I thought having my AOP implement Ordered would help. I set the value returned to 1. I used . This didn't work. I think it's because I misread how Spring orders.

建议订购

当所有建议都希望在运行时运行时会发生什么 相同的连接点? Spring AOP遵循与以下相同的优先级规则 AspectJ确定建议执行的顺序.最高的 优先级建议首先在途中"运行(因此,给定了两个 在提出建议之前,优先级最高的将首先运行). 在 从连接点跳出",则优先级最高的建议将最后运行 (因此,给出了两项建议,其中一项是最高的 优先级将排第二).

What happens when multiple pieces of advice all want to run at the same join point? Spring AOP follows the same precedence rules as AspectJ to determine the order of advice execution. The highest precedence advice runs first "on the way in" (so given two pieces of before advice, the one with highest precedence runs first). "On the way out" from a join point, the highest precedence advice runs last (so given two pieces of after advice, the one with the highest precedence will run second).

当在不同方面定义的两条建议都需要 在相同的连接点运行,除非您另外指定顺序 执行是不确定的.您可以通过以下方式控制执行顺序 指定优先级.这可以通过正常的Spring方式完成, 在中实现org.springframework.core.Ordered接口 方面类或使用Order批注对其进行批注.给定两个 方面,方面从Ordered.getValue()返回较低的值 (或注释值)具有更高的优先级.

When two pieces of advice defined in different aspects both need to run at the same join point, unless you specify otherwise the order of execution is undefined. You can control the order of execution by specifying precedence. This is done in the normal Spring way by either implementing the org.springframework.core.Ordered interface in the aspect class or annotating it with the Order annotation. Given two aspects, the aspect returning the lower value from Ordered.getValue() (or the annotation value) has the higher precedence.

当在同一方面定义的两条建议都需要运行时 在同一连接点,顺序是不确定的(因为没有 通过反射检索声明顺序的方式 javac编译的类).考虑将此类建议方法合并为 每个方面类中每个连接点的一种建议方法,或重构 意见分为单独的方面类-可以订购 在方面方面.

When two pieces of advice defined in the same aspect both need to run at the same join point, the ordering is undefined (since there is no way to retrieve the declaration order via reflection for javac-compiled classes). Consider collapsing such advice methods into one advice method per join point in each aspect class, or refactor the pieces of advice into separate aspect classes - which can be ordered at the aspect level.

所以我取出了order属性.这应该使@Transactional返回Integer.MIN_VALUE.因此,如果我理解上面的引用,它应该最后运行.当我重新部署时,它仍然向后执行.我的AOP,春季TX,MyBatis,关闭MyBatis,关闭SPring Tx,关闭我的AOP.

So I took out the order attribute. This should make @Transactional return Integer.MIN_VALUE. So it should, if I understood the quote above, run last. When I redeployed, it still executed backward. My AOP, Spring TX, MyBatis, Close MyBatis, Close SPring Tx, Close My AOP.

我在做什么错了?

推荐答案

如果未为@Transactional注释配置order属性,则 AbstractPointcutAdvisor (实际上,它的子类之一)将返回

If the order attribute is not configured for @Transactional annotation, then the Advisor which is responsible for transaction attribute - AbstractPointcutAdvisor (in fact, one of the subclasses of it) will return Ordered.LOWEST_PRECEDENCE, which is defined as Integer.MAX_VALUE.

负责自定义AOP建议的Advisor(同一AbstractPointcutAdvisor的子类)将查看实际的

The Advisor which is responsible for custom AOP advice, a subclass of the same AbstractPointcutAdvisor, will look whether the actual Advice implements Ordered interface, and if it does, the provided value will be used during the sorting. If custom AOP advice does not implement Ordered interface, the Advisor returns the same default Ordered.LOWEST_PRECEDENCE and the result of the sorting becomes slightly unpredictable.

因此,为@Transactional注释配置order属性,例如像这样

So, configuring the order attribute for @Transactional annotation e.g. like this

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
           http://www.springframework.org/schema/tx 
           http://www.springframework.org/schema/tx/spring-tx-3.1.xsd>
           .......

           <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" order="[Order for @Transactional]">
<beans/>    

您的自定义AOP建议实施如下所示

and your custom AOP advice implementation looks like this

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

import org.springframework.core.Ordered;

@Aspect
public class CustomAspect implements Ordered {

    @Around(value = "@annotation(CustomAnnotation)")
    public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
    ... 
    }
    ....

    @Override
    public int getOrder() { 
        return [Order for @CustomAnnotation];
    }

    ....

}

然后,您可能会在整个应用程序中拥有所有的排序自由(但还是静态的).

then you probably have all the freedom (yet, statically) with the ordering throughout your application.

在后台,它是

Under the hood, it's AspectJAwareAdvisorAutoProxyCreator who upon a Proxy initialization sorts the Advisors using the comparator org.springframework.aop.aspectj.autoproxy.AspectJPrecedenceComparator which delegates the sorting to OrderComparator. Later on, upon the actual execution, a concrete implementation of AopProxy holds for a specific method an array of the advices, whom it calls interceptors, and this might be used for dynamic reordering, I guess, but none of these things seems to me easily accessible and/or configurable.

我的环境是Spring Beans,TX,AOP-所有版本4.0.3.我也有两个自定义的事务管理器,一个是Hibernate绑定的,一个是JDBC DataSource绑定的,但是我认为这并不重要

My environment is Spring Beans, TX, AOP - all version 4.0.3. I also have two custom Transaction Managers, one is Hibernate-bound and one is JDBC DataSource-bound, but I don't think it matters here

这篇关于自定义Spring AOP周围+ @Transactional的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆