事件驱动编程

一.介绍

事件驱动编程是一种编程范式,其核心思想是程序的执行由事件来驱动

三个基本要素:事件源(什么事件)、事件监听(处理哪些事件)、事件处理(事件怎么处理)

二.案例:模拟游戏用户登录后需要执行的功能

功能:1.添加用户积分  2.发放优惠券  3.记录用户登录日志

@Service
@Slf4j
public class UserService {
    public void addUserScore(String username){
        log.info("给用户{}添加积分",username);
    }
}

@Service
@Slf4j
public class CouponService {
    public void sendCoupon(String username) {
        log.info("给{}发放优惠券", username);
    }
}

@Service
@Slf4j
public class LoggerService {
    public void logUserLogin(String username) {
        log.info("记录用户{}登录日志",username);
    }
}

@Service
@Slf4j
@RequiredArgsConstructor(onConstructor_ = @Lazy)
public class LoginService {
    private final UserService userService;
    private final CouponService couponService;
    private final LoggerService loggerService;

    public void login(String username) {
        log.info("用户{}登录",username);
        userService.addUserScore(username);
        couponService.sendCoupon(username);
        loggerService.logUserLogin(username);
    }
}

@SpringBootApplication
public class EventDrivenProgrammingApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext ioc = SpringApplication.run(EventDrivenProgrammingApplication.class, args);
        LoginService loginService = ioc.getBean(LoginService.class);
        loginService.login("张三");
    }

}

缺点:

1.如果还要新增功能(登录后邮箱提醒),要添加EmailService还要修改LoginService::login方法(违反开闭原则

2.一个登录服务又掺杂积分、优惠券、日志等服务(违反单一职责

三.事件驱动方案

1.创建事件类(继承ApplicationEvent

public class LoginEvent extends ApplicationEvent {
    public LoginEvent(String userName) {
        //父类构造参数为Object类型 通常保存事件相关数据
        super(userName);
    }
}

2.发送事件(不再执行具体任务,替换成事件的发出)

@Service
@Slf4j
@RequiredArgsConstructor(onConstructor_ = @Lazy)
public class LoginService {
    //使用Spring提供的ApplicationEventPublisher发布事件
    private final ApplicationEventPublisher eventPublisher;

    public void login(String username) {
        log.info("用户{}登录",username);
        eventPublisher.publishEvent(new LoginEvent(username));
    }
}

3.监听事件并处理

@Service
@Slf4j
public class UserService {
    @EventListener
    public void addUserScore(LoginEvent loginEvent){
        log.info("给用户{}添加积分",loginEvent.getSource());
    }
}

@Service
@Slf4j
public class CouponService {
    @EventListener
    public void sendCoupon(LoginEvent loginEvent) {
        log.info("给{}发放优惠券", loginEvent.getSource());
    }
}

@Service
@Slf4j
public class LoggerService {
    @EventListener
    public void logUserLogin(LoginEvent loginEvent) {
        log.info("记录用户{}登录日志",loginEvent.getSource());
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值