简介:《Maximo入门培训》面向刚接触企业资产管理系统的开发与实施人员,帮助读者从基础概念过渡到实际定制开发,适合需要了解 Maximo 技术架构、页面与工作流开发及数据库配置的初中级学习者。资料为 1 个 docx 文档,压缩包约 436KB,以培训讲义形式组织,便于按章节查阅。已有 360 人学习,具备一定参考价值。文档从 J2EE、RMI 技术切入,依次覆盖程序结构、页面开发、工作流开发、后台任务与数据库配置,并延伸到代码开发中的 MboSet、Mbo、FldXX 示例及常用类说明。读者可据此建立 Maximo 开发的知识框架,理解模块组成、界面控件、工作流组件与调度任务配置,并借助代码片段熟悉业务对象操作和后台逻辑,为系统实施与二次开发打基础。
1. MAXIMO 二开入门难在哪:从一张工单页面说起
接手一个 MAXIMO 二开需求,最常见的翻车现场是这样的:在应用程序设计器里把字段拖到了新位置,刷新页面纹丝不动;配好工作流节点,工单提交后却一直卡在原地,收件箱里空空如也;照着模板写了个 SimpleCronTask,到了时间点日志里连个影子都没有。这三件事分别对应页面层、工作流层和后台任务层,而多数 MAXIMO 入门培训只告诉你按钮在哪,不告诉你出问题时该去哪一层找原因。这份 MAXIMO 入门培训把技术架构、程序结构、页面开发、工作流、后台任务、数据库配置和 Mbo/MboSet 代码开发串成一条线,适合已经会点界面、想往「能改代码、能定位问题」走的从业者。它不教你背 API,而是把每一层的职责边界和常见坑点摊开讲。
2. 拆开 MAXIMO 程序结构:三个 war 包和 MBO 谁在干活
这一章先把 MAXIMO 的运行期拆开。很多人改页面改不动、写代码不知道放哪个包,根源是没搞清楚三个 war 包和 businessobjects 各自管什么。先把启动链路和分层职责理清,后面页面、工作流、后台任务的排查才有落点。
2.1 启动链路:从 MAXIMOStartupServlet 到 MXServer
MAXIMO 基于 J2EE 架构,业务对象采用 RMI 机制实现,这让分布式计算的设计和编程方便不少。页面逻辑表现和用户交互用 Ajax,体验流畅;对象和关系映射是半自动的,开发效率高,维护也方便;系统基于 XML 技术构架,应用页面和信息交互都用 XML 格式。框架提供自动事务处理,如果需要长事务,得把相关方法纳入一个事务队列。OR 持久化是系统级别的,操作持久层只需要继承 MAXIMO 提供的基类。缓存也是系统级别,数据发生变化时会自动重新加载。日志用扩展的 Log4j,异常做了包装。
这些技术点决定了写代码时的边界:不要自己管数据库连接,不要绕过 Mbo 直接写 SQL,不要在 cronAction 里开长事务。理解这些,后面的代码开发才不会写成「能跑但埋雷」的样子。
启动时,mboweb 的部署描述符里配置了 MAXIMOStartupServlet,load-on-startup 设为 2。这个 servlet 的主要动作是读取 maximo.properties,把配置以 Properties 对象的形式传给 MXServer 的 start 方法。MXServer.start(properties) 做的事情是建立 MXServer 实例并初始化相关信息,它是整个系统服务和应用服务的运行期上下文。
具体来说,MXServer 负责几件事:建立和管理数据连接池、实现 MAXIMO 缓存、调用 MaximoDD 从数据库读取并加载数据字典、实例化系统服务和应用服务对象、注册 RMI、管理 MaxSession 的线程。这些动作发生在应用刚启动时,任何一步失败都会导致后续页面打不开或者业务对象找不到。排查启动问题时,先看 maximo.properties 里的数据库连接和日志配置,再看 MaximoDD 加载数据字典时有没有报错。
提示:启动阶段的问题优先看 catalina 日志和 maximo.properties,不要一上来就翻业务代码。
2.2 分层职责:表现层、控制层、业务层、持久层
MAXIMO 的页面除了登录验证,其余内容都由 XML 提供,这些 XML 存在 MAXPRESENTATION 表里。XML 由 JSP 控制标签组件组成,components 组件和 JavaScript 脚本共同生成需要显示的页面,CSS 文件夹定义通用样式。控制层是 maximouiweb 里的 WebClientServlet,它映射 /ui/*,负责定义页面内容类型并调用 WebClientSession 处理请求。
业务层和持久层都在 businessobjects 里。psdi.app.* 定义业务对象 Mbo 和 MboSet,描述应用相关的业务逻辑;psdi.server.* 定义系统级服务,比如数据库连接管理、session 管理、线程管理、数据对象加载;psdi.util.* 放克隆应用、删除应用、HttpSession 管理、加密解密、客户化应用生成等工具类;psdi.workflow.* 放工作流逻辑;psdi.mbo.* 是核心持久层,实现 OR mapping。
用表格对比一下几个包和文件的职责,排查时对号入座。
| 包/文件 | 职责 | 出问题时先看什么 |
|---|---|---|
| maximouiweb.war | Web 客户端前台,WebClientServlet 处理 /ui/* | 页面 404、请求映射、字符编码 |
| mboweb.war | 启动加载,MAXIMOStartupServlet 读配置 | 启动失败、数据库连接、数据字典加载 |
| businessobjects.jar | 业务对象、系统服务、工具类、工作流、持久层 | 业务规则不生效、Mbo 报错、RMI 异常 |
| properties.jar | MAXIMO 配置文件 | 配置项缺失、连接池参数 |
| MAXPRESENTATION 表 | 页面 XML | 页面字段不显示、布局不生效 |
这个表不是让你背,而是出问题时先锁定范围。页面字段不显示,先查 MAXPRESENTATION 和应用程序设计器;请求直接 404,先查 WebClientServlet 的 url-pattern;业务规则没触发,先查 Mbo 的 appValidate 或 setValue 调用链。把范围缩小了,再去翻具体代码,比上来就全局搜要快得多。
2.3 用日志和异常反推问题在哪一层
MAXIMO 使用并扩充了 Log4j,提供了自己的日志根,可以按具体所属制定日志处理方案。异常也做了包装,给出的是友好异常。这两点对排查很重要:日志能告诉你代码走到哪一步,包装异常能告诉你业务层抛了什么。
我一般的定位顺序是:先看页面表现,是整页打不开还是某个字段不显示;再看请求有没有到 WebClientServlet,可以临时把日志级别调低;然后看业务层日志里有没有 Mbo 抛出的 MXException;最后看数据库有没有 SQL 报错。这个顺序能从外到内缩小范围,避免在表现层改半天其实是持久层字段没配。
举个具体例子。页面打开报「无效的列」,表现层看是页面渲染失败,但根源在持久层:对象属性配了,数据库列没加,或者列名对不上。这时候去应用程序设计器里改布局是白费功夫,得回到数据库配置查对象属性和物理表的映射。再比如工作流节点不流转,先看日志里有没有工作流引擎的异常,再看任务分配的角色有没有人,最后才去看节点连接画得对不对。
注意:调日志级别要在测试环境做,生产环境改完记得改回来,否则日志量会把磁盘吃满。
3. 页面与工作流:用两个设计器落地第一个需求
页面和工作流是 MAXIMO 二开里最常改的两块,也是最容易「看着简单、改完不生效」的两块。这一章把应用程序设计器和工作流设计器的操作边界讲清楚,再给一个工单审批流的完整搭法。
3.1 应用程序设计器能改什么、不能改什么
应用程序设计器是 MAXIMO 里配置页面的主要入口,技术用户和非技术用户都能用,不需要编辑代码。它支持拖放,常见操作包括移动字段和部分、创建新字段、表和标签页。高级一点的功能有创建或复制应用、定义签名选项、编辑工具栏和选择操作菜单。
页面里的常用控件包括文本框、下拉列表、按钮、表、标签页、部分。文本框绑字段,下拉列表绑值列表,按钮触发操作,表和标签页组织内容,部分用于分组。拖控件的时候要注意字段是否已经在当前应用里,没绑定的字段要先在数据库配置里建对象属性,再在应用设计器里加字段。控件和字段的绑定关系错了,页面上能看到控件但存不进值。
我一般会先明确改的是哪个应用、哪个签名选项、哪个组织级别。因为 MAXIMO 的应用可以按组织、站点做差异化配置,改错层级会出现「我明明改了但别人看不到」的情况。
操作步骤大致是这样:打开应用程序设计器,选择目标应用,进入编辑状态,拖放字段或新增控件,保存,然后注销重登测试。新增字段时要注意字段类型和长度,这些会影响到数据库配置。复制应用适合做客户化版本,但复制后要检查菜单和签名选项有没有带过来。
不能改什么?复杂的跨应用业务逻辑、底层表结构、工作流流转规则,这些分别要落到 Mbo 代码、数据库配置和工作流设计器里。应用程序设计器能解决的是「页面长什么样、字段放哪里」,解决不了「数据怎么算、流程怎么走」。这一点分不清,就会在页面上反复折腾却找不到问题。
3.2 工作流节点选型:任务、条件、子过程、等待
工作流设计器用图形界面展示记录可能经过的路径。一个工作流模型包含工作流定义、过程模型、活动、转换条件、相关数据、角色,以及需要激活的内部或外部程序。和工作流相关的应用不少,比如 Actions、Communication Templates、Escalations、Inbox/Assignments Setup、People、Person Groups、Roles、Workflow Application、Workflow Designer、Workflow Inbox。
节点类型选错了,流程就会卡住或者走错分支。下面这张表是我常用的对照。
| 节点类型 | 用在哪 | 连接规则 |
|---|---|---|
| 开始 | 流程起点 | 只能有一个 |
| 停止 | 流程结束,记录脱离工作流控制 | 可以多个 |
| 任务 | 需要用户处理,比如审批 | 至少一个出口,最多一正一反 |
| 条件 | 根据记录信息自动分支 | 必须一正一反,靠 SQL 表达式判断 |
| 手动输入 | 用户从菜单选择下一步 | 用户驱动 |
| 子过程 | 嵌入另一个完整工作流 | 有正向线,可带反向线,遇到停止节点返回主过程 |
| 交互 | 给终端用户提供解决路径选项 | 多个进入,一个退出 |
| 等待 | 等某个事件发生再继续 | 单一退出点 |
任务节点的细节值得多说几句。标题是显示在图标下的文字,描述是对任务节点的说明,应用程序是该流程应用的应用程序,时限是任务需完成的时间长度,超过时限任务会分配给升级角色。任务分配可以指定角色,角色下还能写表达式,只有满足表达式时任务才会分配到该角色,这个选项对控制转发很有用。执行接受操作有两个选项:接受任务的所有人都接受才算任务接受,或者只要任何一个人接受就算任务接受。任务节点最多两个输出操作,正向对应接受,反向对应拒绝,输入操作可以有多个。
条件节点的关键是 SQL 表达式。记录退出条件节点时,所用连接由节点内的 SQL 表达式决定,表达式为真走正连接,为假走负连接。写表达式时要注意字段名和当前对象匹配,别拿工单的字段去判断资产记录。
子过程节点适合把一段可复用的流程抽出来。它遇到停止节点时会沿结束前走过的路线返回主过程,这样可以把终止原因带回主流程。交互节点必须有一个或多个进入操作线,但只能有一个退出操作线,适合把终端用户引导到特定问题的解决路径。等待节点用来对某个操作做特定反应,过程走到这里会暂停,直到指定事件发生才从单一退出点继续。
3.3 一个工单审批流的搭法
拿 demo 库里的过程 APPWFWO 练手最直接。打开工作流设计器,找到这个流程,先看清楚它的开始节点、任务节点和停止节点怎么连的。然后改任务节点的标题、描述、应用程序、时限,把任务分配给一个角色,角色表达式先留空,确保所有人都能收到任务。
操作顺序可以这样走:在工作流设计器里打开 APPWFWO,选中任务节点,改标题和描述,设置应用程序为工单应用,时限设为 24 小时,任务分配选一个测试角色,接受操作选「任何一个人接受就算接受」,保存并激活。然后到工单应用里新建一条工单,提交,打开工作流收件箱看有没有待办。接受任务后观察记录走到下一个节点,拒绝则看反向线走到哪里。
测试时容易忽略的是角色成员。角色没有挂人员,任务分配了也收不到。可以在 People 或 Person Groups 里确认角色成员,再检查 Inbox/Assignments Setup 的收件箱配置。另一个容易忽略的是工作流的激活状态,改完流程没激活,新提交的记录不会按新流程走。
如果流程需要按条件走不同分支,在任务节点后面加条件节点,写 SQL 表达式判断工单金额或优先级。表达式为真走审批通过,为假走退回。条件节点必须一正一反,少一条连接流程就会报错。测试条件节点时,先把表达式写成恒真和恒假两种极端情况,确认连线走对了,再换成真实业务条件。
4. 后台任务、数据库配置与 Mbo/MboSet 代码开发:从界面到持久层
这一章把后台任务、数据库配置和代码开发放在一起,因为它们最终都落到持久层。后台任务定时跑逻辑,数据库配置定义数据长什么样,Mbo/MboSet 代码则是操作这些数据的入口。三块分开看是三个知识点,连起来看是一条从界面配置到代码执行的链路。
4.1 后台任务的界面配置与 SimpleCronTask 代码骨架
后台任务在界面上新建,配置任务名、类名、执行频率和参数。类名要写全限定名,比如 maxdemo.lesson1.CrontaskTest。执行频率按业务需求设,别设得太密,尤其是涉及全表扫描的逻辑。
代码侧继承 SimpleCronTask,实现 init() 和 cronAction() 两个方法。init() 里做参数初始化,cronAction() 里写具体业务逻辑。下面是一个最小骨架。
package maxdemo.lesson1; import psdi.common.cron.task.SimpleCronTask; import psdi.util.MXException; public class CrontaskTest extends SimpleCronTask { @Override public void init() throws MXException { super.init(); // 参数初始化:读取任务参数、准备上下文对象 } @Override public void cronAction() { // 每次调度触发时执行,注意异常处理和日志 try { // 业务代码,比如批量更新工单状态 } catch (Exception e) { // 记录日志,不要吞异常 } } }init() 在任务初始化时调用,适合放一次性准备动作;cronAction() 是每次调度触发时执行的方法。常见错误是把业务逻辑写进 init(),结果任务只在启动时跑一次。另一个错误是 cronAction() 里不捕获异常,任务抛异常后调度器可能不再触发,日志里也看不到明显痕迹。
注意:cronAction 里不要做长事务,涉及多条记录更新时拆成小批次,避免锁表。
4.2 数据库配置四件套与更新数据库
数据库配置包括新建对象、创建对象属性、索引和关系。对象对应业务实体,对象属性对应字段,索引影响查询性能,关系定义对象之间的关联。这四样配完,还要更新数据库,否则应用能打开但一操作就报列不存在。
操作步骤:打开管理方式,进入数据库配置,新建对象并设置表名,创建对象属性并设置字段名、类型、长度,按查询需求加索引,配置关系,然后应用配置变更,开始配置数据库。更新数据库时会生成并执行 DDL,把新对象和属性落到物理库。
对象属性的类型和长度要和实际业务匹配。字符串字段长度设太小,后面改起来要动数据库;设太大又浪费空间。索引不是越多越好,写多读少的表加太多索引会拖慢保存速度。关系配置错了,页面上的关联查询会查不到数据。
更新数据库前先备份,这是血泪经验。我见过一次在测试环境改对象属性,没备份就直接应用变更,结果字段类型从字符串改成数字,历史数据转换失败,回退花了半天。后来我养成习惯:先在测试库跑一遍,确认 DDL 没问题,再动正式库。
4.3 MboSet 构造方法与 getMboInstance
MboSet 是 MAXIMO 持久层的核心类,核心超类是 psdi.mbo.MboSet。应用程序对象和 MboSet 类直接关联,创建对象时必须指定关联的 MboSet 类。MboSet 类必须继承 psdi.mbo.MboSet,实现 psdi.mbo.MboSetRemote 接口,并且必须定义构造方法,实现 getMboInstance(MboSet arg0) 方法,在该方法里返回 Mbo 类的实例。
下面是一个客户化 MboSet 的骨架。
package maxdemo.lesson1; import java.rmi.RemoteException; import psdi.mbo.Mbo; import psdi.mbo.MboServerInterface; import psdi.mbo.MboSet; <p> <a href="https://download.csdn.net/download/tm6230610/3831658" style="color:#ec7500;font-size:14px;"> 本文还有配套的精品资源,点击获取 </a> <img alt="menu-r.4af5f7ec.gif" src="https://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif" style="width:16px;margin-left:4px;vertical-align:text-bottom;cursor:text;"> </p>