【问题标题】:Pass object between before and after advice在通知之前和之后传递对象
【发布时间】:2017-06-02 09:37:43
【问题描述】:

我的问题与Pass object between before and after advice? 中的问题相同,但是接受的答案在我的情况下不起作用,我想要求对此主题进行一些澄清。

实际上,我正在使用around 建议,但我必须更改它。让我们考虑一个例子:

public Object registerLog( ProceedingJoinPoint jpoint)
{
    SomeObject so = getSomeData( jpoint.getArgs());
    Object result = jpoint.proceed();
    getMoreData( result, so);
    log( so);
}

我的proceed() 方法是将对象插入数据库。在这种情况下,我在事务提交之前记录INSERT 的结果,这不是很好。这就是为什么我想将around 建议拆分为beforeafter,所以当记录已经在数据库中时,我可以登录after。但是,在将对象存储到数据库之前,我仍然需要获取对象的一些数据。

当然,解决方案必须是线程安全的,所以我不能只在我的方面类中添加一个SomeObject 成员。从链接的问题中,我了解到ThreadLocal,到目前为止,这是我找到的最佳解决方案。但是,我以前从未使用过它,我想问一下是否有其他解决方案。也许有一种方法可以在处理方面时强制事务提交(我现在不确定这是否是个好主意)?

更新详情

我有两个切入点:

<aop:pointcut id="mngrPointcut" expression="execution(* com.mngr.Foo.*(..))"/>
<aop:pointcut id="savePointcut" expression="execution(* com.mngr.Foo.save(..))"/>

第一个切入点有建议

<aop:advisor advice-ref="txAdvice" pointcut-ref="mngrPointcut"/>

建议在哪里

<tx:advice id="txAdvice" transaction-manager="txManager">
    <tx:attributes>
        <tx:method name="select*,search*,get*" propagation="REQUIRED" rollback-for="Exception" read-only="true"/>
        <tx:method name="*" propagation="REQUIRED" rollback-for="Exception"/>
    </tx:attributes>
</tx:advice>

对于第二个切入点,我有方面

<aop:aspect ref="logAspect">
    <aop:around method="registerLog" pointcut-ref="savePointcut"/>
</aop:aspect>

当调用com.mngr.Foo.save() 时,两个切入点都有效。可能是因为申报顺序,先触发mngrPointcut,开始新的交易。然后savePointcut 被触发,开始一个切面。正如我上面提到的,方面负责记录。由于触发切入点的顺序,对象在存储到数据库之前被记录,这是错误的。我认为我必须使用beforeafter 通知而不是around,所以当事务已经提交时,我可以在after 部分调用log() 方法。

【问题讨论】:

  • 你需要遵守周围的建议,只要确保你的方面在 spring 的事务方面之前执行。如果您使用 aspectj,“声明优先级”就是您要查找的内容。
  • 为什么around 不适用于您的情况?拆分为beforeafter 可以得到什么?请详细说明,最好是一些示例代码。
  • @NándorElődFekete 谢谢。设置交易和建议的顺序解决了这个问题。考虑将其发布为答案。
  • @kriegaex 我想控制事务提交的时刻,并使用after 建议当业务对象已经在数据库中时必须执行的方法。请检查更新以获取一些详细信息。

标签: java spring aop aspectj spring-aop


【解决方案1】:

感谢 Nándor Előd Fekete 的评论,我通过设置交易顺序和建议解决了这个问题。低阶强制方面在进场时更早运行,在出场时反向运行。无序方面在有序方面之后运行。

【讨论】:

    【解决方案2】:

    如果您在方面优先级方面遇到问题,将切入点类型从 around 更改为 after 将无济于事。相反,你想让你的切面实现Ordered 接口,或者用@Order 注释它们,两者都在Spring AOP manual 中描述。请在本章后面进一步搜索“ordered”一词,以便(不是双关语)查看一些示例代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多