春天的事件监听器被调用了两次 [英] Event Listeners in spring is called twice

查看:129
本文介绍了春天的事件监听器被调用了两次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Spring事件侦听器的问题,在我的Web应用程序中,我们将不胜感激.

I am an issue with Spring Event Listeners In my Web app, Any immediate help will be appreciated.

事件侦听器被注册并调用两次(如果我具有循环依赖性).

我有服务类,该类在其他方法上具有@transaction注释

I have service class, this has @transaction annotation on another methods

@Service(PBSTaskService.BEAN_NAME)
public class PBSTaskServiceImpl extends StandardServiceImpl<ITask> implements          PBSTaskService,ApplicationListener<SurveyDefinitionPublishedEvent>
{
    @Autowired
    private AutoSelectTaskSliceRouteSyncService autoSelectTaskSliceRouteSyncService; //  CYCLIC Dependency
    @Override
    public void onApplicationEvent(SurveyDefinitionPublishedEvent event)
     { 
      System.out.println("PBSTSImpl"); // THIS IS CALLED TWICE
     }
... Other method with @Transaction Annotation
}


@Service(AutoSelectTaskSliceRouteSyncService.BEAN_NAME)
public class AutoSelectTaskSliceRouteSyncServiceImpl implements AutoSelectTaskSliceRouteSyncService
{ 
      @Autowired private PBSTaskService pbsTaskService; // CYCLIC dependency
}

现在,如果我从头等舱中删除AutoSelectTaskSliceRouteSyncSyncService依赖项,则一次调用OnApplicationEvent,否则调用两次.

Now If I remove AutoSelectTaskSliceRouteSyncService dependency from First Class, OnApplicationEvent is called once, else twice.

我调试了一下,发现 SimpleApplicationEventMulticaster.getApplicationListeners(myEvent):有两个代理对象,一个用Cglib包装,另一个用默认对象包装.但是只有在具有循环依赖性的情况下才有两个.如果我删除循环依赖项,则它只有一个代理对象,而CGLIB增强了该代理对象. 我的Tx批注: 我曾尝试使用proxy-target-class ="true或false",但没有运气.

I debugged and found out that SimpleApplicationEventMulticaster.getApplicationListeners(myEvent) : Has two proxy object, one wrapped with Cglib and another default one. But it has two only in case if it has cyclic dependency. If I remove Cyclic dependency, it has only one proxy object and that one is enahnces by CGLIB. my Tx annotation : I had tried it with proxy-target-class="true or false" but no luck.

您可能想看看

https://jira.springsource.org/browse/SPR-7940?focusedCommentId=98988&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-98988

推荐答案

ApplicationEvent侦听器在我们的Web应用程序的更多位置被两次调用.这是我们遇到的情况之一.

ApplicationEvent Listeners are called twice at many more places in our web app. This is one of scenarios that we caught up.

原因: 侦听器被注册两次.返回两个代理,它们包装在一个侦听器实例上.返回的代理是1.动态Jdk接口代理2.带有@transactions批注的Cglib代理.

Reason : Listeners are registered twice. Two proxy are returned wrapped over one instance of listeners. Proxy returned are 1. Dynamic Jdk Interface proxy 2. Cglib Proxy, when we have @transactions annotations.

要重新创建这三点,必须:

To recreate these three point are must:

  1. 您的侦听器必须实现ApplicationListener2.您的侦听器必须与另一个类3具有循环依赖关系.您的侦听器必须具有一个@Transaction注释的方法.

我创建了一个单独的项目,可以在其中使用spring和hibernate进行复制.如果2和3不能同时出现,那么我们是安全的.

I have created a separate project where I am able to reproduce it with spring and hibernate. If 2 and 3 are not present together, then we are safe.

解决方案 我尝试了很多关于spring和transaction配置的调整,但是没有运气.最后,在我的演示项目中,将事务处理代码移至另一个类,以便侦听器没有任何@transaction注释,然后它对我有用.

Solution I tried many tweaks with spring and transaction configuration but no luck. Then finally with my demo project when I moved the transaction code to another class, so that the listeners do not have any @transaction annotations then it worked for me.

这篇关于春天的事件监听器被调用了两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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