2014-02-18 4 views
3

Я проблема с прослушивателями событий в Spring В моем веб-приложении всякая немедленная помощь будет оценена по достоинству.Слушатели Слушатели весны называются дважды

Слушатели слушаний регистрируются и вызывается дважды, если у меня есть циклическая зависимость.

У меня есть класс обслуживания, это имеет @transaction аннотации других методы

@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 
} 

Теперь Если удалить AutoSelectTaskSliceRouteSyncService зависимости от первого класса, OnApplicationEvent вызывается один раз, еще два раза.

Я отлаживал и выяснял, что SimpleApplicationEventMulticaster.getApplicationListeners (myEvent): имеет два прокси-объекта, один из которых завершен Cglib и другой по умолчанию. Но он имеет два только в том случае, если он имеет циклическую зависимость. Если я удалю циклическую зависимость, у нее будет только один прокси-объект, и он будет включен в CGLIB. my Tx аннотация: Я пробовал это с прокси-target-class = "true или false", но не повезло.

Вы можете взглянуть на

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

ответ

2

ApplicationEvent Приёмников называются дважды во многих других местах в нашем веб-приложение. Это один из сценариев, которые мы догнали.

Причина: Слушатели регистрируются дважды. Два прокси возвращаются в один экземпляр слушателей. Возврат прокси-сервера: 1. Прокси-сервер динамического Jdk-интерфейса 2. Прокси-сервер Cglib, когда у нас есть аннотации @transactions.

Чтобы воссоздать эти три точки являются должны:

  1. Ваши слушатели должны реализующий ApplicationListener 2. Ваши слушатели должны иметь циклическую зависимость с другим классом 3.your слушателей должен иметь один метод с аннотацией @Transaction.

Я создал отдельный проект, где я могу воспроизвести его с помощью пружины и спящего режима. Если 2 и 3 нет вместе, тогда мы в безопасности.

Решение Я пробовал много настроек с пружиной и конфигурацией транзакций, но не повезло. Затем, наконец, с моим демо-проектом, когда я переместил код транзакции в другой класс, так что у слушателей нет аннотаций @transaction, тогда это сработало для меня.

+0

Столкнувшись с той же проблемой в Grails 2.4.5, когда класс обслуживания класса как ApplicationListener. – AndreyT

-1

В классах Spring, анонированных с помощью @Service или @Component, которые реализуют интерфейс ApplicationListener, получат повторяющиеся события. Чтобы устранить проблему, чтобы получать только отдельные события, просто удалите аннотацию @Service или @Compontent.

Смежные вопросы