ApplicationListener调用了两次

时间:2015-11-11 23:56:13

标签: spring spring-mvc events

我正在做一个Spring MVC webapp,然后我想在确认/激活目的下向新注册用户发送电子邮件。然后我写一个ApplicationEvent和ApplicationListener<>类。问题是,监听器将调用两次,因此我收到2封电子邮件,并在我的数据库中有2个令牌字符串。

如何解决这个问题?

以下代码,

了ApplicationEvent:

public class OnRegistrationSuccessEvent extends ApplicationEvent {

    private String appUrl;
    private Locale locale;
    private User user;

    public OnRegistrationSuccessEvent(String appUrl, Locale locale, User user) {
        super(user);
        this.appUrl = appUrl;
        this.locale = locale;
        this.user = user;
    }

    // getters, setters
}

ApplicationListener:

@Component
public class RegistrationListener implements ApplicationListener<OnRegistrationSuccessEvent> {

    @Autowired
    UserService userService;

    @Autowired
    MessageSource messages;

    @Autowired
    JavaMailSender javaMailSender;

    @Override
    public void onApplicationEvent(OnRegistrationSuccessEvent event) {
        this.confirmationEmail(event);
    }

    private void confirmationEmail(OnRegistrationSuccessEvent event){
       // register token in DB, send mail
    }

    private SimpleMailMessage buildEmailMessage(OnRegistrationSuccessEvent event, User user, String token) {
       //build some message
    }
}

我用@Controller调用事件:

eventPublisher.publishEvent(new OnRegistrationSuccessEvent(URL, request.getLocale(), user));

感谢您的帮助,

1 个答案:

答案 0 :(得分:0)

假设publishEvent ApplicationEventPublisher#publishEvent来自其中一个内置ApplicationContext子类型的实现,那么它只会调用onApplicationEvent一次。

我认为您遇到的是拥有多个RegistrationListener个对象。 ApplicationContext会将发布到其父事件的任何事件传播到其父上下文。我相信你的每个root和servlet应用程序上下文中都有一个RegistrationListener bean。查看您的配置以了解发生的情况。 (您也可以在this内记录RegistrationListener(或代表实例的内容)来确认这一点。)

  

如何解决这个问题?

将您的配置更改为仅在Listener的{​​{1}}内生成并注册一个ApplicationContext