十堰响应式网站,低价网站设计多少钱,南通营销网站建设,wordpress 配置模板1 “你日渐平庸#xff0c;甘于平庸#xff0c;将继续平庸。”——《以自己喜欢的方式过一生》 2. “总是有人要赢的#xff0c;那为什么不能是我呢?”——科比布莱恩特 3. “你那么憎恨那些人#xff0c;和他们斗了那么久#xff0c;最终却要变得和他们一样#xff0c;… 1 “你日渐平庸甘于平庸将继续平庸。”——《以自己喜欢的方式过一生》 2. “总是有人要赢的那为什么不能是我呢?”——科比·布莱恩特 3. “你那么憎恨那些人和他们斗了那么久最终却要变得和他们一样人世间没有任何理想值得以这样的沉沦作为代价。”——马尔克斯《百年孤独》 4. “如果结果不如你所愿就在尘埃落定前奋力一搏。”——《夏目友人帐》 5. “人有逆天之时天无绝人之路。”——《醒世恒言》 6. “有些事不是看到了希望才去坚持而是因为坚持才会看到希望。”——《十宗罪》 7. “维持现状意味着空耗你的努力和生命。”——纪伯伦 Spring * 事件驱动编程 推荐
KOI技术-事件驱动编程前端
一. 概念
事件驱动编程是面向事件的不同于传统的基于顺序的编程它旨在当事件发生时再采用行动进行处理的一种编程范式。它使得程序以松耦合的方式进行粘合实现部分解耦。
二. 主要解决的问题
1.代码的松耦合
将系统复杂的功能拆分为多个部分每个部分抽象为一个组件组件与组件之间通过良好定义的接口进行通信那么他们之间通信的触发若采用引入依赖调用的方式便使得类之间产生了强关系属于功能耦合若把他们之间调用的触发抽象为事件就能降低、解除组件之间的耦合关系。
事件驱动模型实际上是将组件之间的耦合关系转移到了“事件Event”上但是对于某个领域而言事件Event一般具有通用性并且不会频繁变更实现逻辑所以事件驱动模型可以很好地实现组件之间的解耦。
2.异步编程的需要MQ 主要用于分布式
业务场景中顺序、阻塞式地执行任务会遇到一些比较耗时的中间步骤但是不希望整个流程都停下来等待这些中间步骤完成而是触发一个异步操作然后继续执行当前任务在收到异步操作处理完成的消息之后再执行相关的处理。
使用事件驱动模型实现异步任务的一般思路是当遇到耗时较大、没有同步执行要求的操作时针对这个操作触发一个事件将这个事件加入到任务队列中直到有一个进程线程能够获取并执行这个任务才开始执行这个任务。
这里大家可能会想到MQMQ不就是干这个的吗对它确实是做这个的但是是想一下我就是一个单机系统或者我是一个底层编程框架为了实现解耦异步我就要引入MQ是不是有点大材小用强制上车的意思。所以事件编程适用于小范围或者小场景需求但在框架编程中大量使用。
3.状态模型状态机日志记录
这个场景理解起来比较简单但是处理这种场景的方式却很多。 比如我们需要对实体状态的变更进行监控有没有想到禅道-项目管理中的最新动态对请求的接口做一些日志记录但日志有可能需要异步。这里大家可能会联想到AOP确实在状态监控的实现上考虑到的简单方式就是切面变成这里是想告诉大家除了切面事件驱动也可以实现。各有优劣。
三. 设计模式
可能大家在查询资料或者学习过程中会看到事件编程或者状态管理时会碰到设计模式中的 “观察者模式”确实这个模式“很符合”这个场景那问题来了需要了解他吗 我的建议是需要为啥懂了它手写一个高大上的模式在项目上岂不是更好对于理解底层架构来说也提供了思路岂不更好。
观察者模式是使用频率较高的设计模式之一。 定义对象间一种一对多的依赖关系使得当每一个对象改变状态则所有依赖于它的对象都会得到通知并自动更新。是一种对象行为型模式。
观察者模式的别名包括发布-订阅Publish/Subscribe模式、模型-视图Model/View模式、源-监听器Source/Listener模式或从属者Dependents模式。 看到这些名称有没有想到技术上的一些概念MQ MVVM HODOOP 监听器 一些概念 Subject目标被观察者它是指被观察的对象。 ConcreteSubject具体目标具体目标是目标类的子类通常它包含经常发生改变的数据当它的状态发生改变时向它的各个观察者发出通知。 Observer观察者观察者将对观察目标的改变做出反应观察者一般定义为接口该接口声明了更新数据的方法 update()因此又称为抽象观察者。 ConcreteObserver具体观察者在具体观察者中维护一个指向具体目标对象的引用它存储具体观察者的有关状态这些状态需要和具体目标的状态保持一致它实现了在抽象观察者Observer 中定义的 update()方法。 图中涉及UML的关系要理解图比较重要看的懂才可以继续。关联实线实心箭头泛化继承 实线空心实现虚线空心聚合关联关系的一种实现空心菱形
四. JDK中的观察者模式如何自行实现不是从0开始
观察者模式在 Java 语言中的地位非常重要。在 JDK 的 java.util 包中提供了 Observable 类以及 Observer 接口它们构成了 JDK 对观察者模式的支持可以去查看下源码写的比较严谨。
这种方式不建议使用了因为在jdk9之后废弃且存在线程不安全问题
**推荐**java.util.concurrent包中的ConcurrentHashMap和CopyOnWriteArrayList以及java.util.EventListener相关的API来构建自己的观察者模式实现
五. Spring 的事件驱动编程正文开始
1. 概念
事件ApplicationEvent 是所有事件对象的父类。ApplicationEvent 继承自 jdk 的 EventObject, 所有的事件都需要继承 ApplicationEvent, 并且通过 source 得到事件源。 Spring 也为我们提供了很多内置事件ContextRefreshedEvent、ContextStartedEvent、ContextStoppedEvent、ContextClosedEvent、RequestHandledEvent。事件监听ApplicationListener也就是观察者继承自 jdk 的 EventListener该类中只有一个方法 onApplicationEvent。当监听的事件发生后该方法会被执行。事件源ApplicationContextApplicationContext 是 Spring 中的核心容器在事件监听中 ApplicationContext 可以作为事件的发布者也就是事件源。因为 ApplicationContext 继承自 ApplicationEventPublisher。在 ApplicationEventPublisher 中定义了事件发布的方法publishEvent(Object event)事件管理ApplicationEventMulticaster用于事件监听器的注册和事件的广播。监听器的注册就是通过它来实现的它的作用是把Applicationcontext 发布的 Event 广播给它的监听器列表。
2. 核心类
ApplicationEvent 事件类ApplicationListener 监听器泛型事件类EventListener 注解同ApplicationListener 作用于方法上参数是事件类ApplicationEventPublisher 自动发布事件的处理类常用的他是一个借口自定义时可重写它ApplicationEventPublisherAware 接口类用于业务处理中它包含 setApplicationEventPublisher 的方法用于指定ApplicationEventPublisherApplicationEventMulticaster 用于事件监听器的注册和事件的广播编程不涉及但是需要了解下
3. 说一下 原理懂了基本就OVER了涉及源码不懂暂时可以
1. 广播器 类结构 ApplicationEventMulticaster接口提供了添加/移除监听器以及广播事件给监听器的行为。 AbstractApplicationEventMulticaster抽象类提供了基础的监听器注册/移除以及查找能力。 SimpleApplicationEventMulticaster类提供了事件广播功能。
2. 注册广播器和监听器
Spring容器初始化时 org.springframework.context.support.AbstractApplicationContext 在refresh()方法中会进行广播器和监听器的注册。
初始化事件广播器(initApplicationEventMulticaster)注册监听器(registerListeners)事件广播 publistEventmulticastEvent
4. 实操效果
定义事件
EqualsAndHashCode(callSuper true)
Data
Builder
public class DemoEvent extends ApplicationEvent {private String name;public DemoEvent(String source) {super(source);this.name source;}public DemoEvent(Object source, Clock clock) {super(source, clock);}
}定义事件监听
方式一采用注解 适合业务编程Component
public class DemoEventListener {EventListener(DemoEvent.class)public void demoListener(DemoEvent event){System.out.println(event.getName());}
}方式二 适合底层框架编程
public class DemoEventListenerIm implements ApplicationListenerDemoEvent {Overridepublic void onApplicationEvent(DemoEvent event) {System.out.println(event.getName());}
}定义事件发布可不写框架编程需要
Component
public class DemoPublisher implements ApplicationEventPublisherAware {private ApplicationEventPublisher applicationEventPublisher;Overridepublic void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {this.applicationEventPublisher applicationEventPublisher;}public void publishEvent(DemoEvent event) {System.out.println(publish event);applicationEventPublisher.publishEvent(event);}}测试
SpringBootTest(classes EventApplication.class)
RunWith(SpringRunner.class)
public class TestApplication {Autowiredprivate ApplicationEventPublisher publisher;Testpublic void demoEvenTest() {DemoEvent demoEvent new DemoEvent(hello);publisher.publishEvent(demoEvent);System.out.println(laile);}
}5. 其他注意点 事务监听器 EnableTransactionManagement开启事务支持TransactionalEventListener标识事务监听器。 发布事件的操作必须在事务(Transactional)内进行否则监听器不会生效也可以将fallbackExecution标志设置为true(TransactionalEventListener(fallbackExecution true))可以配置在事务的哪个阶段来监听事务(默认在事务提交后监听),TransactionalEventListener(phase TransactionPhase.AFTER_COMPLETION)。 异步支持 EnableAsync开启异步支持Async标识监听器异步处理。开启异步执行后方法的异常不会抛出只能在方法内部处理。 条件监听 EventListener(condition “#event.message.contains(‘important’)”) 用于按照条件处理数据可用与区分数据处理 监听器顺序 Order控制多个监听器的执行顺序值越小监听器越先执行。
到这里您基本就了解了事件编程思路。 下面我们聊一聊前端的事件编程。KOI技术-事件驱动编程前端