Spring 中的事件机制 ApplicationEventPublisher

事件机制在一些大型项目中被常常使用,因而 Spring 专门提供了一套事件机制的接口,方便咱们运用。本文来讲说 ApplicationEventPublisher 的使用。

在设计模式中,观察者模式能够算得上是一个很是经典的行为型设计模式,猫叫了,主人醒了,老鼠跑了,这一经典的例子,是事件驱动模型在设计层面的体现。

另外一模式,发布订阅模式每每被人们等同于观察者模式,但个人理解是二者惟一区别,是发布订阅模式须要有一个调度中心,而观察者模式不须要,例如观察者的列表能够直接由被观察者维护。不过二者即便被混用,互相替代,一般不影响表达。

java 和 spring 中都拥有 Event 的抽象,分别表明了语言级别和三方框架级别对事件的支持。

Spring 的文档对 Event 的支持翻译以后描述以下:

ApplicationContext 经过 ApplicationEvent 类和 ApplicationListener 接口进行事件处理。 若是将实现 ApplicationListener 接口的 bean 注入到上下文中,则每次使用 ApplicationContext 发布 ApplicationEvent 时,都会通知该 bean。本质上,这是标准的观察者设计模式。

下面经过 demo,看一个电商系统中对 ApplicationEventPublisher 的使用。

咱们的系统要求,当用户注册后,给他发送一封邮件通知他注册成功了。

而后给他初始化积分,发放一张新用户注册优惠券等。设计

定义一个用户注册事件:

public class UserRegisterEvent extends ApplicationEvent{
    public UserRegisterEvent(String name) { //name即source
        super(name);
    }
}

ApplicationEvent 是由 Spring 提供的全部 Event 类的基类,为了简单起见,注册事件只传递了 name(能够复杂的对象,但注意要了解清楚序列化机制)。

再定义一个用户注册服务(事件发布者):

@Service
public class UserService implements ApplicationEventPublisherAware {
    public void register(String name) {
        System.out.println("用户:" + name + " 已注册!");
        applicationEventPublisher.publishEvent(new UserRegisterEvent(name));
    }
    private ApplicationEventPublisher applicationEventPublisher;
    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }
}

须要注意的是,服务必须交给 Spring 容器托管。ApplicationEventPublisherAware 是由 Spring 提供的用于为 Service 注入 ApplicationEventPublisher 事件发布器的接口,使用这个接口,咱们本身的 Service 就拥有了发布事件的能力。用户注册后,再也不是显示调用其余的业务 Service,而是发布一个用户注册事件。

建立邮件服务,积分服务,其余服务(事件订阅者)等:

@Service
public class EmailService implements ApplicationListener<UserRegisterEvent> {
    @Override
    public void onApplicationEvent(UserRegisterEvent userRegisterEvent) {
        System.out.println("邮件服务接到通知,给 " + userRegisterEvent.getSource() + " 发送邮件...");
    }
}

事件订阅者的服务一样须要托管于 Spring 容器,ApplicationListener 接口是由 Spring 提供的事件订阅者必须实现的接口,咱们通常把该 Service 关心的事件类型做为泛型传入。处理事件,经过 event.getSource() 便可拿到事件的具体内容,在本例中即是用户的姓名。 其余两个 Service,也一样编写,实际的业务操做仅仅是打印一句内容便可,篇幅限制,这里省略。

最后咱们使用 Springboot 编写一个启动类。

@SpringBootApplication
@RestController
public class EventDemoApp {
    public static void main(String[] args) {
        SpringApplication.run(EventDemoApp.class, args);
    }
    @Autowired
    UserService userService;
    @RequestMapping("/register")
    public String register(){
        userService.register("xttblog.com");
        return "success";
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值