我的问题与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
建议拆分为before
和after
,因此当记录已经在数据库中时,我可以登录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
,开始一个方面。如上所述,方面负责记录。由于触发切入点的顺序,对象在存储到数据库之前会被记录,这是错误的。我认为我必须使用before
和after
建议而不是around
,因此我可以在log()
部分调用after
方法,当事务已经comitted。
答案 0 :(得分:1)
感谢NándorElődFekete的评论,我通过设定交易顺序和建议来解决问题。低阶强制方面在前进的路上和在出路上反向运行。没有订购的方面在订单之后运行。
答案 1 :(得分:0)
如果您遇到方面优先级问题,将切入点类型从around
更改为after
将无济于事。相反,您希望使方面实现Ordered
界面,或者@Order
按type PostContainer
= VideoContainer Video
| PodcastContainer Podcast
注释,两者都如Spring AOP manual中所述。还请在章节中进一步搜索“订购”这一术语(没有双关语),以查看一些示例代码。