Spring中的发布订阅

模型构成

  • 事件类
ApplicationEvent 继承 java.util.EventObject, 
我们需要继承ApplicationEvent,必要时候为事件添加一些属性
  • 事件发布类
ApplicationContext 继承了org.springframework.context.ApplicationEventPublisher,
我们需要通过ApplicationContext.publisEvent(event)发布事件
  • 事件处理类
ApplicationListener 继承了java.util.EventListener,
我们需要实现ApplicationListener接口,并覆写处理事件的方法,完成事件处理逻辑

适用场景

如果在应用中发生了某些事件,事件会被拦截和处理就好了,这样就有了很大的灵活性,至少代码不会紧密的耦合在一起,

代码的解耦就是业务的解耦,业务A的代码不用手动的调用业务B的代码,业务B只需要监听相关事件,根据事件处理业务就可以了。

使用示例

  • 事件定义
public class SendEmailEvent extends ApplicationEvent {
    private String message;
 
    public SendEmailEvent(Object source, String message) {
        super(source);
        this.message = message;
    }
 
    public String sendEmail(){
        return message;
    }
 
}
  • 事件发布
@Component
@Slf4j
public class SendEmailEventPublisher {
    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;
 
    public void publish(final String message) {
        log.info("publis a SendEmailEvent,message:{}", message + " time: " + LocalTime.now());
        SendEmailEvent sendEmailEvent = new SendEmailEvent(this, message);
        applicationEventPublisher.publishEvent(sendEmailEvent);
    }
 
}
  • 事件监听(a)
@Component
@Slf4j
public class SendEmailListener implements ApplicationListener<SendEmailEvent> {
    @Override
    public void onApplicationEvent(SendEmailEvent sendEmailEvent) {
        String s = sendEmailEvent.sendEmail();
        log.info("SendRegisterEmailListener message: " + s+" time: "+ LocalTime.now());
    }
}
  • 事件监听(b)
@Component
@Slf4j
public class SendEmailListener2 {
    @EventListener
    public void sendEmmail(SendEmailEvent sendEmailEvent){
        String s = sendEmailEvent.sendEmail();
        log.info("SendRegisterEmailListener message: " + s+" time: "+ LocalTime.now());
    }
 
}

分析

  • 监听如何确定对应的事件?
根据发布与订阅接口的参数类型进行匹配
  • 默认是同步执行还是异步执行?
Spring事件默认是同步的,通过在启动类Application上加上@EnableAsync开启异步。
使用方法注解@Async可以作用在监听器的执行方法上,异步执行。
@Async不带参数默认使用SpringBoot默认的线程池。推荐使用自定义的线程池.
@Configuration
public class ThreadPoolConfig {
 
    @Bean("executor")
    public Executor getExecutor() {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(10,
                20,
                60,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue(10000));
        return executor;
    }
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值