java 事件驱动模型(事件发布和监听@EventListener)

一、需要了解的概念

1、Aware机制:

Spring 容器在创建 bean 的过程中,会检查 bean 是否实现了某些特定的 Aware 接口,如果实现了,则会在合适的时机调用相应的 setter 方法,将相关的对象注入到 bean 中。

2、ApplicationEvent:

是Spring框架中的一个核心类,它表示Spring应用中的事件。这个类基于观察者模式,为Bean与Bean之间的消息通信提供了支持,是业务解耦的一种实现。常用于标识继承的类为一个事件类。

3、ApplicationEventPublisherAware:

ApplicationEventPublisherAware接口使得 bean 能够访问 Spring 的 ApplicationEventPublisher(事件发布者)。这个发布者允许 bean 发布应用事件,这些事件随后会被注册为监听器的其他 bean 接收。常用于定义发布事件的方法,给业务需要的地方进行调用。

二、代码示例

1、声明一个事件

java 复制代码
import org.springframework.context.ApplicationEvent;
// 定义事件--如:邮件事件
public class EmailEvent extends ApplicationEvent {
    public EmailEvent(Object source) {
        super(source);
    }
}

2、定义事件的发布方法

java 复制代码
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Component;

// 定义发布事件方法,用于业务发布各种事件
@Component
public class EmailPublish implements ApplicationEventPublisherAware, ApplicationContextAware {
    // ApplicationEventPublisherAware实现了Aware接口,容器加载EmailPublish时,会促发Aware机制
    // 本例EmailPublish对象实现了ApplicationEventPublisherAware接口,所以在创建bean过程会调用setApplicationEventPublisher方法,setApplicationEventPublisher的入参ApplicationEventPublisher会自动从容器中传入,所以生成的DataEventPublish对象就包含了初始化好的applicationEventPublisher属性对象。

    // Spring 框架中的一个核心组件,俗称应用上下文,常用来获取和管理应用中的bean对象
    private ApplicationContext applicationContext;

    //  Spring 框架中的一个核心组件,它提供了事件发布的功能
    private ApplicationEventPublisher applicationEventPublisher;

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

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }

    // 生明发布邮件事件的方法
    public void publishEmail(Object source) {
        // applicationEventPublisher.publishEvent为向运行容器中发布事件,参数指定了发布什么类型的事件
        // 发布EmailEvent事件,监听EmailEvent事件的地方会被执行
        applicationEventPublisher.publishEvent(new EmailEvent(source));
    }

}

3、调用发布

java 复制代码
@Service
public class EventServiceImpl implements EventService {
@Autowired
private EmailPublish publish;
    @Override
    public void testPublishEvent(EvDto evDto) {
        System.out.println("进入service");
        // 调用发布邮件的事件方法
        publish.publishEmail(evDto);
    }
}

4、监听事件,处理业务

java 复制代码
import com.alibaba.fastjson.JSON;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
// 监听事件,实现业务
@Component
public class EmailPublishListener {

    @Transactional(propagation = Propagation.NEVER)
    @EventListener(classes = {EmailEvent.class})
    public void listenerEvent(EmailEvent event){
        System.out.println("进入邮件监听方法");
        Object source = event.getSource();
        System.out.println("调用的入参数据:"+ JSON.toJSONString(source));
        // 执行业务...
    }
}

思路:

定义事件--定义发布方法--定义监听方法--调用发布

三、优势

本例的事件驱动模型是一种典型的观察者设计模式,它使得组件之间的解耦更为容易,也使得代码更加灵活和可扩展。通过发布和监听事件,你可以在不直接依赖其他组件的情况下实现组件间的通信和协作。

优点:

1、解耦:观察者设计模式实现了观察者与被观察者之间的解耦,降低了两者之间的耦合关系。这使得两者可以各自独立地改变,而不需要对另一方进行大量的修改。

2、灵活性和可扩展性:由于观察者设计模式允许动态地添加或删除观察者,因此系统具有很好的灵活性和可扩展性。新的观察者可以很容易地添加到系统中,而无需修改被观察者的代码。

3、事件驱动:观察者设计模式基于事件驱动,当被观察者状态发生改变时,会自动通知所有注册的观察者。这种机制使得系统响应更加及时和准确。

学海无涯苦作舟!!!

相关推荐
kimnoic1 小时前
Python数据库学习心得:SQLite、MySQL、PostgreSQL优缺点
开发语言·python
别动我齐刘海2 小时前
C++ 工程化学习
java·linux·前端·c++·学习·机器学习·机器人
必须得开心呀2 小时前
python编写带界面的软件,需要安装哪些插件
开发语言·python
code2cat3 小时前
Java进阶篇之AtomicLongFieldUpdater:把累计额度留在对象字段中
java·cas·并发编程
WeiXin_DZbishe3 小时前
基于springboot城市公交实时运营与调度系统-计算机毕设 附源码【课程设计】66173
java·vue.js·spring boot·后端·python·php·课程设计
泡茶喝茶写代码3 小时前
A股量化数据工程:从 REST 接口到策略信号(第 18 篇):放量缩量异动扫描
java·python·股票数据api·股票数据api接口·股票api数据接口·股票量化数据api·股票量化数据接口
wewowilling3 小时前
认识微服务
java·运维·微服务·springcloud
代码什么用4 小时前
Java Web 7-10
java·servlet
沫璃染墨4 小时前
《Qt从零入门系列(十三):QSS样式表详解——从选择器与层叠规则到控件美化实战》
开发语言·css·c++·qt·ui·qt6.3·qss