Java 在通知之前和之后传递对象
我的问题与中的相同,但接受的答案在我的情况下不起作用,我想要求对这个主题进行一些澄清 事实上,我正在使用Java 在通知之前和之后传递对象,java,spring,aop,aspectj,spring-aop,Java,Spring,Aop,Aspectj,Spring Aop,我的问题与中的相同,但接受的答案在我的情况下不起作用,我想要求对这个主题进行一些澄清 事实上,我正在使用环绕建议,但我必须改变它。让我们考虑一个例子: public Object registerLog( ProceedingJoinPoint jpoint) { SomeObject so = getSomeData( jpoint.getArgs()); Object result = jpoint.proceed(); getMoreData( result, so
环绕
建议,但我必须改变它。让我们考虑一个例子:
public Object registerLog( ProceedingJoinPoint jpoint)
{
SomeObject so = getSomeData( jpoint.getArgs());
Object result = jpoint.proceed();
getMoreData( result, so);
log( so);
}
我的procedure()
方法正在将对象插入数据库。在这个场景中,我在事务提交之前记录INSERT
的结果,这不是很好。这就是为什么我想将分为之前的和之后的,这样当记录已经在数据库中时,我就可以在之后登录。然而,在将对象存储到数据库之前,我仍然需要获取它的一些数据
当然,解决方案必须是线程安全的,所以我不能只向方面类添加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
,启动一个方面。如上所述,aspect负责日志记录。由于触发切入点的顺序,对象在存储到数据库之前会被记录,这是错误的。我认为我必须使用之前
和之后
通知,而不是周围的,这样当事务已经提交时,我可以在之后的部分调用log()
方法。如果在方面优先级方面有问题,将切入点类型从
前后的更改为
之后的,不会有帮助。相反,您希望让方面实现有序
接口,或者通过@Order
对其进行注释,这两种方法都如中所述。还请在本章中进一步搜索术语“ordered”(没有双关语)以查看一些示例代码。多亏了Nándor Előd Fekete的评论,我通过设置事务和建议的顺序解决了问题。低阶强制相位在进入时提前运行,在退出时反向运行。未排序的方面在具有排序的方面之后运行 您需要遵守周围的建议,只是确保您的方面在spring的事务方面之前执行。如果您使用的是aspectj,那么您需要的就是“声明优先级”。为什么在您的情况下不起作用?在
之前
和之后
拆分为有什么可能的好处?请详细说明,最好是用一些示例代码。@NándorElődFekete谢谢。设置事务和通知的顺序解决了这个问题。考虑把它作为回答。@ KRIGEAX,我想控制事务发生的时刻,使用<代码> > 对业务对象已经在数据库中时必须执行的方法的建议。请查看更新以了解一些详细信息。