SpringBoot中事件的使用

        项目中很多场景可以使用事件来对系统进行解耦,让系统更便于维护和扩展。SpringBoot项目默认是支持事件的,我们只需要自定义事件,然后发布事件,之后监听事件处理业务逻辑即可。SpringBoot中我们会用到事件抽象类ApplicaltionEvent,事件监听接口ApplicationListener,事件发布接口ApplicationEventPublisher或ApplicationContextAware。

事件发布无论是用ApplicationEventPublisher还是ApplicationContextAware都可以,实际上都是调用了publishEvent(ApplicationEvent event)方法进行事件发布。

从Springboot源码来看,ApplicationContextAware 接口定义了一个set方法,用于注入ApplicationContext 对象,而ApplicationContext继承ApplicationEventPublisher接口。

public interface ApplicationContextAware extends Aware {
    void setApplicationContext(ApplicationContext var1) throws BeansException;
}
@FunctionalInterface
public interface ApplicationEventPublisher {
    default void publishEvent(ApplicationEvent event) {
        this.publishEvent((Object)event);
    }

    void publishEvent(Object var1);
}
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
    @Nullable
    String getId();

    String getApplicationName();

    String getDisplayName();

    long getStartupDate();

    @Nullable
    ApplicationContext getParent();

    AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
}

使用示例如下:

1.定义一个事件,事件需要继承ApplicationEvent,否则无法发布。

package com.xmc.event;

import org.springframework.context.ApplicationEvent;

import java.util.Map;

/**
 * 定义一个事件
 */
public class SmsEvent extends ApplicationEvent {
    // 事件参数
    private Map<String, String> map;
    public SmsEvent(Object source, Map<String,String> map) {
        super(source);
        this.map = map;
    }

    public Map<String,String> getParam() {
        return map;
    }
}

2.编写Service层代码,用于事件发布。

以下分别是通过注入ApplicationEventPublisher 对象和实现ApplicationContextAware接口通过setter方式注入ApplicationContext对象的方式,来调用publishEvent方法发布事件。

@Service
public class SmsService {
    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;

    /**
     * 发布事件
     * @param smsEvent
     */
    public void SendSms(SmsEvent smsEvent) {
        applicationEventPublisher.publishEvent(smsEvent);
    }
}
package com.xmc.service;

import com.xmc.event.SmsEvent;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;

@Service
public class SmsService2 implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    /**
     * 发布事件
     * @param smsEvent
     */
    public void SendSms(SmsEvent smsEvent) {
        applicationContext.publishEvent(smsEvent);
    }


}

3.编写controller层代码

package com.xmc.controller;

import com.xmc.event.SmsEvent;
import com.xmc.service.SmsService;
import com.xmc.service.SmsService2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
public class UserRegisterController {
    @Autowired
    private SmsService smsService;

    @Autowired
    private SmsService2 SmsService2;

    @GetMapping("/registerUser")
    public String registerUser()  {
        Map<String,String> map = new HashMap<>();
        map.put("phone", "12345678901");
        SmsEvent smsEvent = new SmsEvent(this, map);
        smsService.SendSms(smsEvent);
        return "注册成功";
    }

    @GetMapping("/registerUser2")
    public String registerUser2()  {
        Map<String,String> map = new HashMap<>();
        map.put("phone", "12345678902");
        SmsEvent smsEvent = new SmsEvent(this, map);
        SmsService2.SendSms(smsEvent);
        return "注册成功2";
    }
}

4.编写listener监听器,用监听器来执行发送短信任务。一般来说实现了ApplicationListener接口后,要把事件类型作为泛型传入。如果不传入事件类型的泛型, 则重写onApplicationEvent方法后就是public void onApplicationEvent(ApplicationEvent event), 需要通过event.getSource()拿到关心的类型再做处理。

package com.xmc.listener;

import com.xmc.event.SmsEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

/**
 * 事件监听器
 */
@Component
public class SmsListener implements ApplicationListener<SmsEvent> {
    @Override
    public void onApplicationEvent(SmsEvent smsEvent) {
        System.out.println("正在向手机号:" + smsEvent.getParam().get("phone") + "发送短信");
    }
}

测试结果:

正在向手机号:12345678901发送短信

正在向手机号:12345678902发送短信

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值