apache mina 学习(十二)-----状态机(stateMachine)

2023-12-09 04:58

本文主要是介绍apache mina 学习(十二)-----状态机(stateMachine),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

mina状态机的工作原理:

mina中引入了StateContext对象,顾名思义是一个状态上下文对象,用来保存当前的状态,当代理state对象的方法被调用的时候,这个上下文对象会通知stateContextLookup的实例去从方法参数中获取stateContext,通常情况下StateContextLookup 的实现类会循环方法的参数进行查找,并创建指定的对象,并从这个对象中得到一个上下文对象,如果没定义上下文对象,StateContextLookup 会创建一个新的并存放到对象中。

当代理mina的IoHandler时,我们将用IoSessionStateContextLookup实例来查找Iosession中的参数,然后用IoSession的属性来为每一个Session存储一个StateContext对象。这样同样的状态机可以让每个mina的session使用,而不会彼此影响。

我们使用StateMachineProxyBuilder创建一个代理时,我们一直没有我们一直没有配置StateContextLookup 使用哪种实现。如果没有配置,系统会使用SingletonStateContextLookup 。SingletonStateContextLookup 总是不理会方法中传递给它的参数,它一直返回一个相同的状态上下文。很明显,这中方式在多个客户端
并发的情况下使用同一个同一个状态机是没有意义的。

请努力看懂下面的例子:这个事件Event {id = "messageReceived", arguments =[ArrayList a = [...], Integer b = 1024]}下面的方法将和这个事件是等价的:

// All method arguments matches all event arguments directly
@Transition(on = "messageReceived")
public void messageReceived(ArrayList l, Integer i) { ... }// Matches since ((a instanceof List && b instanceof Number) == true)
@Transition(on = "messageReceived")
public void messageReceived(List l, Number n) { ... }// Matches since ((b instanceof Number) == true)
@Transition(on = "messageReceived")
public void messageReceived(Number n) { ... }// Methods with no arguments always matches
@Transition(on = "messageReceived")
public void messageReceived() { ... }// Methods only interested in the current Event or StateContext always matches
@Transition(on = "messageReceived")
public void messageReceived(StateContext context) { ... }// Matches since ((a instanceof Collection) == true)
@Transition(on = "messageReceived")
public void messageReceived(Event event, Collection c) { ... }

但是下面的方法不会和这个事件相匹配:

// Incorrect ordering
@Transition(on = "messageReceived")
public void messageReceived(Integer i, List l) { ... }// ((a instanceof LinkedList) == false)
@Transition(on = "messageReceived")
public void messageReceived(LinkedList l, Number n) { ... }// Event must be first argument
@Transition(on = "messageReceived")
public void messageReceived(ArrayList l, Event event) { ... }// StateContext must be second argument if Event is used
@Transition(on = "messageReceived")
public void messageReceived(Event event, ArrayList l, StateContext context) { ... }// Event must come before StateContext
@Transition(on = "messageReceived")
public void messageReceived(StateContext context, Event event) { ... }

状态继承:

StateMachine.handle(Event)方法如果不能找到一个transaction和当前的事件在当前的状态中匹配的话就是去找他得父状态,依次类推,知道找到为止,所以我们有时候很需要状态的继承:

@State    public static final String A = "A";
@State(A) public static final String B = "A->B";
@State(A) public static final String C = "A->C";
@State(B) public static final String D = "A->B->D";
@State(C) public static final String E = "A->C->E";
运行:

public static void main(String[] args) {...deck.load("The Knife - Silent Shout");deck.play();deck.pause();deck.play();deck.stop();deck.eject();deck.play();
}
可能会保以下的错误,至少我第一次是报错的:

...
Tape stopped
Tape ejected
Exception in thread "main" o.a.m.sm.event.UnhandledEventException: 
Unhandled event: org.apache.mina.statemachine.event.Event@15eb0a9[id=play,...]at org.apache.mina.statemachine.StateMachine.handle(StateMachine.java:285)at org.apache.mina.statemachine.StateMachine.processEvents(StateMachine.java:142)
这个异常我们无法处理,所以 我们将添加一个指定的事务来处理所有不能匹配的事件:

@Transitions({@Transition(on = "*", in = EMPTY, weight = 100),@Transition(on = "*", in = LOADED, weight = 100),@Transition(on = "*", in = PLAYING, weight = 100),@Transition(on = "*", in = PAUSED, weight = 100)
})
public void error(Event event) {System.out.println("Cannot '" + event.getId() + "' at this time");
}
运行:

Tape stopped
Tape ejected
Cannot 'play' at this time.
当然,定义所有状态的root更有效:

public static class TapeDeckHandler {@State public static final String ROOT = "Root";@State(ROOT) public static final String EMPTY = "Empty";@State(ROOT) public static final String LOADED = "Loaded";@State(ROOT) public static final String PLAYING = "Playing";@State(ROOT) public static final String PAUSED = "Paused";...@Transition(on = "*", in = ROOT)public void error(Event event) {System.out.println("Cannot '" + event.getId() + "' at this time");}
}




这篇关于apache mina 学习(十二)-----状态机(stateMachine)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/472546

相关文章

深入理解Apache Kafka(分布式流处理平台)

《深入理解ApacheKafka(分布式流处理平台)》ApacheKafka作为现代分布式系统中的核心中间件,为构建高吞吐量、低延迟的数据管道提供了强大支持,本文将深入探讨Kafka的核心概念、架构... 目录引言一、Apache Kafka概述1.1 什么是Kafka?1.2 Kafka的核心概念二、Ka

Java进阶学习之如何开启远程调式

《Java进阶学习之如何开启远程调式》Java开发中的远程调试是一项至关重要的技能,特别是在处理生产环境的问题或者协作开发时,:本文主要介绍Java进阶学习之如何开启远程调式的相关资料,需要的朋友... 目录概述Java远程调试的开启与底层原理开启Java远程调试底层原理JVM参数总结&nbsMbKKXJx

使用Apache POI在Java中实现Excel单元格的合并

《使用ApachePOI在Java中实现Excel单元格的合并》在日常工作中,Excel是一个不可或缺的工具,尤其是在处理大量数据时,本文将介绍如何使用ApachePOI库在Java中实现Excel... 目录工具类介绍工具类代码调用示例依赖配置总结在日常工作中,Excel 是一个不可或缺的工http://

Apache伪静态(Rewrite).htaccess文件详解与配置技巧

《Apache伪静态(Rewrite).htaccess文件详解与配置技巧》Apache伪静态(Rewrite).htaccess是一个纯文本文件,它里面存放着Apache服务器配置相关的指令,主要的... 一、.htAccess的基本作用.htaccess是一个纯文本文件,它里面存放着Apache服务器

Debezium 与 Apache Kafka 的集成方式步骤详解

《Debezium与ApacheKafka的集成方式步骤详解》本文详细介绍了如何将Debezium与ApacheKafka集成,包括集成概述、步骤、注意事项等,通过KafkaConnect,D... 目录一、集成概述二、集成步骤1. 准备 Kafka 环境2. 配置 Kafka Connect3. 安装 D

Java深度学习库DJL实现Python的NumPy方式

《Java深度学习库DJL实现Python的NumPy方式》本文介绍了DJL库的背景和基本功能,包括NDArray的创建、数学运算、数据获取和设置等,同时,还展示了如何使用NDArray进行数据预处理... 目录1 NDArray 的背景介绍1.1 架构2 JavaDJL使用2.1 安装DJL2.2 基本操

深入理解Apache Airflow 调度器(最新推荐)

《深入理解ApacheAirflow调度器(最新推荐)》ApacheAirflow调度器是数据管道管理系统的关键组件,负责编排dag中任务的执行,通过理解调度器的角色和工作方式,正确配置调度器,并... 目录什么是Airflow 调度器?Airflow 调度器工作机制配置Airflow调度器调优及优化建议最

SpringBoot使用Apache Tika检测敏感信息

《SpringBoot使用ApacheTika检测敏感信息》ApacheTika是一个功能强大的内容分析工具,它能够从多种文件格式中提取文本、元数据以及其他结构化信息,下面我们来看看如何使用Ap... 目录Tika 主要特性1. 多格式支持2. 自动文件类型检测3. 文本和元数据提取4. 支持 OCR(光学

Apache Tomcat服务器版本号隐藏的几种方法

《ApacheTomcat服务器版本号隐藏的几种方法》本文主要介绍了ApacheTomcat服务器版本号隐藏的几种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需... 目录1. 隐藏HTTP响应头中的Server信息编辑 server.XML 文件2. 修China编程改错误

SpringBoot使用Apache POI库读取Excel文件的操作详解

《SpringBoot使用ApachePOI库读取Excel文件的操作详解》在日常开发中,我们经常需要处理Excel文件中的数据,无论是从数据库导入数据、处理数据报表,还是批量生成数据,都可能会遇到... 目录项目背景依赖导入读取Excel模板的实现代码实现代码解析ExcelDemoInfoDTO 数据传输