随笔-生活工作点滴

ApplicationEventPublisherAware事件

2019-07-05  本文已影响0人  可可西里的星星

ApplicationEventPublisherAware事件发布详解

为了达到解耦的目的,一个类应当只做一件事,例如,用户进行注册时,需要创建注册相关的类,来完成注册事务。但是,如果注册成功时,还需要发送验证邮件,以及手机校验码,很多人为了方便,直接在注册类中将发送邮件和发送短信的代码一并写入。这样做会导致后面维护的困难,耦合性高。

我们可以通过事件发布来达到解耦的目的,事件的原理如下。
image
事件的发布者发布事件,事件的监听这对对应的事件进行监听,当监听到对应的事件时,就会触发调用相关的方法。因此,在事件处理中,事件是核心,是事件发布者和事件监听者的桥梁。

对应到上面的案例,我们可以在用户注册成功后发布事件,事件监听者监听到用户注册成功的事件后,触发发送邮件和发送短信的业务。由于要触发发送邮件和短信,因此要从事件发布者那里获取对应的邮件地址和手机号码,而这些信息是通过事件这个桥梁进行连接的,所以,事件中必须包含邮件地址和手机号码这两个属性。

分析了以上过程后我们开始编写代码:

1.springboot框架搭建:

 1.1 pom
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  <modelVersion>4.0.0</modelVersion>  <groupId>com.stu</groupId>  <artifactId>springBootEvent</artifactId>  <version>0.0.1-SNAPSHOT</version>    <parent>       <groupId>org.springframework.boot</groupId>     <artifactId>spring-boot-starter-parent</artifactId>     <version>2.0.1.RELEASE</version>        <relativePath/>     </parent>     <dependencies>  <dependency>          <groupId>org.springframework.boot</groupId>         <artifactId>spring-boot-starter-web</artifactId>        </dependency>  </dependencies>  </project>
1.2properties文件配置:
server.port=9898server.servlet.context-path=/listener
1.3启动类:
package com.stu; import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController; @SpringBootApplication@RestControllerpublic class ListenerApplication { public static void main(String[] args) {        SpringApplication.run(ListenerApplication.class, args); }       @RequestMapping("/")    public String healthyCheck() {              return "Ok";    }}
2.事件类:由于需要发送邮件和短信,因此需要封装邮件地址和手机号码到事件类中,为了方便,直接将用户注册填写的信息封装成User类,并将该类直接作为事件的属性。
package com.stu.event; import org.springframework.context.ApplicationEvent; import com.stu.entity.User; public class UserRegisterEvent extends ApplicationEvent {   private static final long serialVersionUID = -5481658020206295565L;     private User user;      //谁发布的这个事件,souce就是谁(对象) public UserRegisterEvent(Object source, User user) {        super(source);      this.user = user;   }       public User getUser() {             return user;    }   }

3. Controller层:封装用户注册的参数为User类,并调用service进行注册

package com.stu.controller; import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController; import com.stu.entity.User;import com.stu.service.UserRegisterService; @RestController@RequestMapping("/user")public class UserRegisterController {      @Autowired  private UserRegisterService userRegisterService;        @RequestMapping("/register")    public String register(User user) {             //进行注册              userRegisterService.register(user);     return "[controller]注册用户成功!";           }   }

4.Service层:执行用户注册,并发布事件

package com.stu.service; import org.springframework.context.ApplicationEventPublisher;import org.springframework.context.ApplicationEventPublisherAware;import org.springframework.stereotype.Service; import com.stu.entity.User;import com.stu.event.UserRegisterEvent; @Servicepublic class UserRegisterService implements ApplicationEventPublisherAware {      private ApplicationEventPublisher applicationEventPublisher;        public boolean register(User user) {                //用户注册      System.out.println("[service]用户["  + user + "]注册成功!");              //消息发布      applicationEventPublisher.publishEvent(new UserRegisterEvent(this, user));                      return true;    }       @Override   public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {     this.applicationEventPublisher = applicationEventPublisher;         }}

5.事件监听:监听到事件发布后,自动执行onApplicationEvent方法,所以该类需要有IOC来管理,类上要加@Component注解

package com.stu.listener; import org.springframework.context.ApplicationListener;import org.springframework.stereotype.Component; import com.stu.event.UserRegisterEvent; @Componentpublic class EventListener implements ApplicationListener<UserRegisterEvent> {  @Override   public void onApplicationEvent(UserRegisterEvent event) {               //发邮件       System.out.println("正在发送邮件至: " + event.getUser().getEmail());               //发短信       System.out.println("正在发短信到: " + event.getUser().getPhoneNum());         }}

6.实体类:

package com.stu.entity; public class User { private Integer id; private String name;    private String phoneNum;    private String email;   public Integer getId() {        return id;  }   public void setId(Integer id) {     this.id = id;   }   public String getName() {       return name;    }   public void setName(String name) {      this.name = name;   }   public String getPhoneNum() {       return phoneNum;    }   public void setPhoneNum(String phoneNum) {      this.phoneNum = phoneNum;   }   public String getEmail() {      return email;   }   public void setEmail(String email) {        this.email = email; }   @Override   public String toString() {      return "User [id=" + id + ", name=" + name + ", phoneNum=" + phoneNum + ", email=" + email + "]";   }   }

代码写好之后访问地址:http://localhost:9898/listener/user/register?id=1&name=john&phoneNum=13111111111&email=123@163.com可以得到以下结果:

控制台:

[service]用户[User [id=1, name=john, phoneNum=13111111111, email=123@163.com]]注册成功!
正在发送邮件至: 123@163.com
正在发短信到: 13111111111

页面显示:

[controller]注册用户成功!
上一篇 下一篇

猜你喜欢

热点阅读