Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在通知之前和之后传递对象_Java_Spring_Aop_Aspectj_Spring Aop - Fatal编程技术网

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,我想控制事务发生的时刻,使用<代码> > 对业务对象已经在数据库中时必须执行的方法的建议。请查看更新以了解一些详细信息。