Flowable-服务-骆驼任务
目录
- 定义
- 图形标记
- XML内容
- Flowable与Camel集成
- 使用示例
- 设计Came路由代码
定义
Camel 任务不是 BPMN 2.0 规范定义的官方任务,在 Flowable 中,Camel 任务是作为一种特殊的服务
任务来实现的。主要做路由工作的。
图形标记
由于 Camel 任务不是 BPMN 2.0 规范的“官方”任务,因此没有提供其专用图标。在 bpmnjs
中 Camel 任务我们就使用服务任务代替,如图所示:

XML内容
Camel 任务在 Flowable 中定义为一个专用的服务任务,这个服务任务的 type 属性设置为 camel。
Camel 任务的 XML 表示格式如下:
<serviceTask id="camelTask1" name="Camel " flowable:type="camel" />
以上在流程定义的服务任务上定义 Camel 类型即可,集成逻辑都将通过 Camel 容器委托。
Flowable与Camel集成
本节将具体介绍 Flowable 与 Camel 集成的过程,以及 Flowable 基于 Camel 扩展出来的各种特性
和用法。
- Camel 的配置与依赖
默认情况下,使用 Camel 任务时,Flowable 引擎在 Spring 容器中查找 camelContext Bean。camelContext
Bean 用于定义 Camel 容器装载的 Camel 路由,Camel 路由可以在 Spring 配置文件中定义,也可以按照指
定的 Java 包装载路由:
<camelContext id="camelContext" xmlns="http://camel.apache.org/schema/spring"><packageScan><package>com.dragon.test.bpmn.camel.route</package></packageScan></camelContext>
通过以上配置,在初始化时 CamelContext 时会把 com.dragon.test.bpmn.camel.route 中
的路由定义类(继承自 RouteBuilder,后文会讲解)注册到 CamelContext 对象中。CamelContext 是 Camel
中一个很重要的概念,它横跨了 Camel 服务的整个生命周期,并且为 Camel 服务的工作环境提供支撑,
Camel 中的各个 Service 的关联衔接通过 CamelContext 上下文对象完成。
由于 Flowable 的配置文件采用的是 spring bean 配置文件格式,因此在 Flowable 与 Camel 集成时,以上
配置内容可以直接加在 Flowable 的配置文件中。
如果想要定义多个 camelContext,或想使用不同的 Bean 名字,可以在 Camel 任务定义中通过以下方
式指定:
<serviceTask id="camelTask1" name="Camel " flowable:type="camel" />
需要注意的是,如果要使用 Camel 任务,需要在项目中包含 flowable-camel 模块依赖及 Camel 相关依
赖,Maven 依赖定义如下:
<dependency><groupId>org.flowable</groupId><artifactId>flowable-camel</artifactId><version>xxx</version></dependency><dependency><groupId>org.apache.camel</groupId><artifactId>camel-http</artifactId><version>xxx</version></dependency>
- 定义Camel路由
Camel 最重要的特色之一就是路由,路由用于应用中的通信或者应用间通信。Camel 的路由需要通过
我们手动编排的方式,在指定的(或可变的)端点间进行数据的传输、过滤、转换等操作。Camel 路由
易于使用的一个特性是端点 URI,通过指定 URI,可以确定要使用的组件以及该组件是如何被配置的。
然后可以决定将消息发送到由该 URI 配置的组件,或者使用该组件发出消息。
flowable 的 flowable-camel 模块提供了 Camel 与 Flowable 通信的桥梁,当流程流转到 Camel 任务后流程
引擎将调用 Camel 执行对应的路由,同时可以选择把流程变量传递给路由,在路由处理结束后还可以有
选择地把路由得到的结果以流程变量的方式回传给流程实例。
我们可以通过 Java DSL 构建 Camel 路由(也可通过 XML 配置,这里不做介绍),需要继承
org.apache.camel.builder.RouteBuilder 类,然后实现其中的 configure 方法。Flowable 与 Camel 集成后,一个
典型的路由定义类如下:
public class GetIpInfoCamelCallRoute extends RouteBuilder {@Overridepublic void configure() {from("flowable:CamelTaskProcessTest:afef07cc915df4771a54048fe871e9c9e?copyVariablesToProperties=true").toD("http://ip-api.com/json/${exchange.getProperty('ip')}?lang=zh-CN&bridgeEndpoint=true").process(new ResultProcessor());}
}
在以上路由定义类的 configure 方法中,通过 Java 的 DSL 语言(域特定语言)描述路由规则,from
和 to 是两个关键字,Camel 会从 from 声明的起始端点将消息路由至 to 声明的终点。所有的路由都以一
个 from 开始,它接受端点 URI 作为参数。flowable-camel 模块定义了“flowable”类型的路由 URI 协议,以
上面的配置为例,from 端点(endpoint)的格式包含冒号和问号分隔的几个部分,各部分的含义如表 15.3
所示。
flowable-camel 模块提供的 URI 协议
| 属性 | 描述 |
|---|---|
| flowable | 协议开头,指向引擎端点 |
| CamelTaskProcessTest | 流程定义 Key |
| afef07cc915df4771a54048fe871e9c9e | 流程定义中 Camel 服务的 id |
| copyVariablesToProperties=true | 路由 URI 的参数 |
- 路由URI配置
我们可以通过在 URI 中附加一些参数,使用 Flowable 提供的几种不同的行为,从而实现干预 Camel
组件的功能。本节将介绍 URI 中支持的参数,包括输入参数和输出参数两类。
3.1. 输入参数
Flowable 提供了三种输入参数,可以用于控制将流程变量复制到 Camel 的策略,可配置的输入参数如
表所示:参数 对应flowable行为类 描述 copyVariablesToProperties org.flowable.camel.impl.CamelBehaviorDefaultImpl 默认配置,将 Flowable 的流程变量复制为 Camel 参数,在路由中可以通过形如${property.variableName}的表达式获取到参数值。 copyCamelBodyToBody org.flowable.camel.impl.CamelBehaviorCamelBodyImpl 只将名为"camelBody"的 Flowable 流程变量复制为 Camel 消息体。如果 camelBody 的值是 Map 对象,在路由中可以通过形如 b o d y [ v a r i a b l e N a m e ] 的表达式获取到参数值;如果 c a m e l B o d y 的值是纯字符,可以使用 {body[variableName]}的表达式获取到参数值;如果 camelBody 的值是纯字符,可以使用 body[variableName]的表达式获取到参数值;如果camelBody的值是纯字符,可以使用{body}表达式获取。 copyVariablesToBodyAsMap org.flowable.camel.impl.CamelBehaviorBodyAsMapImpl 把 Flowable 的所有流程变量复制到一个 Map 对象里,作为 Camel 的消息体。,在路由中可以通过形如${body[variableName]}的表达式获取到参数值。 以如下路由规则为例:
from("activiti:CamelTaskProcess:camelTask1?copyVariablesToProperties=true").to("log:org.activiti.camel.examples.SimpleCamelCall");
这里的配置在 URI 中附加了 copyVariablesToProperties=true,表示将 Flowable 的流程变量复制成 Camel
参数。
3.2. 输出参数
同样的,Flowable 提供了几种输出参数,可以用于控制将 Camel 执行结果复制到流程变量的策略,可
配置的输出参数如表所示:
flowable-camel 模块提供的 URI 协议:
| 参数 | 描述 |
|---|---|
| default | 默认配置。如果 Camel 消息体是一个 Map 对象,则在路由执行结束后将其中每一个属性复制为 Flowable 的流程变量;否则将整个 Camel 消息体复制到名为"camelBody"的流程变量。 |
| copyVariablesFromProperties | 将 Camel 参数以相同的名称复制为 Flowable 流程变量。 |
| copyVariablesFromHeader | 将 Camel Header 中的内容以相同的名称复制为 Flowable 流程变量。 |
| copyCamelBodyToBodyAsString | 与 default 相同,但如果 Camel 消息体不是 Map 对象,则首先将其转换为字符串,然后再复制到名为"camelBody"的流程变量 |
| 以如下路由规则为例: |
from("activiti:CamelTaskProcess:camelTask1?copyVariablesFromProperties=true").to("log:org.activiti.camel.examples.SimpleCamelCall");
这里的配置在 URI 中附加了 copyVariablesFromProperties=true,表示将 Camel 参数以相同的名称复制
为 Flowable 流程变量中。
4. 异步Camel调用
默认情况下,Camel 任务是同步执行的,流程执行到 Camel 任务后将处于等待状态,直到 Camel 执
行结束并返回结果后,才离开 Camel 任务往下继续流转。如果 Camel 任务执行时间比较长,或者某些场
景下不需要同步执行,则可以使用 Camel 任务的异步功能,将 Camel 任务的 async 参数设置为 true 即可
启用这个功能:
<serviceTask id="camelTask1" name=" Camel " activiti:type="camel"activiti:async="true"/>
设置这个参数后,Camel 路由会由 Flowable 作业执行器异步启动。
5. 通过Camel启动流程
前面几节介绍了如何整合 Camel 与 Flowable,以及两者如何通信,都是先启动 Flowable 流程实例,然
后在流程实例中启动 Camel 路由。反过来,也可以通过 Camel 任务启动或调用流程实例,其 Camel 的路
由规则可以这么设计:
from("flowable:ParentProcess:camelTaskForStartSubprocess").to("flowable:subProcessCreateByCamel");
其中,from 声明的起始端点的 URI 分为三个部分:"flowable"协议开头,父流程定义 key,Camel 任务
id;to 声明的终止端点的 URI 包含两个部分:"flowable"协议开头,子流程定义 key。
使用示例
下面我们看一个使用 Camel 任务的示例流程,如图所示,用于调用外部第三方服务自动化地
获取 IP 信息。流程发起后首先通过 Camel 任务调用外部 Web 服务查询 IP 信息,然后通过邮件任务发送
查询结果给申请人
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xbHKxnwk-1690689579641)(…/public/images/service/camel-task.png)]
Camel 路由配置整合到 Flowable 的配置文件中内容如下:
<process id="CamelTaskProcessTest" name="服务-骆驼任务" isExecutable="true"><startEvent id="a4192d69b9d5a4d1faf42b7c9741d0d48" /><sequenceFlow id="a0db08b7fe8d74803b11b59179c6e0a57" sourceRef="a4192d69b9d5a4d1faf42b7c9741d0d48" targetRef="afef07cc915df4771a54048fe871e9c9e" /><serviceTask id="afef07cc915df4771a54048fe871e9c9e" name="获取Ip信息" flowable:type="camel"><extensionElements><flowable:formData /><flowable:assigneeType>static</flowable:assigneeType></extensionElements></serviceTask><sequenceFlow id="Flow_1ce3l0r" sourceRef="afef07cc915df4771a54048fe871e9c9e" targetRef="Activity_1n9nrw6" /><serviceTask id="Activity_1n9nrw6" name="发送邮件" flowable:type="mail"><extensionElements><flowable:field name="to"><flowable:expression>liuwenjun05101@163.com</flowable:expression></flowable:field><flowable:field name="subject"><flowable:string>IP信息查询结果</flowable:string></flowable:field><flowable:field name="html"><flowable:expression><html><body><p>用户&lt;b&gt;${userName}&lt;/b&gt;你好,&lt;br/&gt;</p><p>你查询的IP&lt;b&gt;${ip}&lt;/b&gt;的信息为:&lt;br/&gt;</p><p>省份:${regionName} 城市:${city}</p><p>互联网服务提供商:${isp}</p></body></html></flowable:expression></flowable:field><flowable:field name="charset"><flowable:string>utf-8</flowable:string></flowable:field></extensionElements></serviceTask><endEvent id="Event_1l6yldo" /><sequenceFlow id="Flow_1h6rd9m" sourceRef="Activity_1n9nrw6" targetRef="Event_1l6yldo" /></process>
在以上配置中:
1、流程引擎配置使用的是 SpringProcessEngineConfiguration,这是因为 Flowable Camel集成时,
需要通过 SpringProcessEngineConfiguration 获取 camelContext,相关细节读者可自行查看源代码。
2、Camel 路 由 是 通 过 Spring 的 环 境 下 扫 描 路 由 配 置 实现的, Spring 会 扫 描 包 路 径
com.dragon.test.bpmn.camel.route下的 Route 类加载到 camelContext 中。
设计Came路由代码
Camel 路由 Route 的代码如下:
package com.didichuxing.bpm.demo.chapter15.camel.route;
import com.didichuxing.bpm.demo.chapter15.camel.processor.ResultProcessor;
import com.didichuxing.bpm.demo.chapter15.camel.processor.TransformProcessor;
import org.apache.camel.builder.RouteBuilder;
public class GetIpInfoCamelCallRoute extends RouteBuilder {
@Override
public void configure() throws Exception {from("activiti:CamelTaskProcess:camelTask1?copyVariablesToProperties=true").toD("http://ip-api.com/json/${property.ip}?lang=zh-CN&bridgeEndpoint=true").process(new ResultProcessor());
}
}
在以上代码中:
⑴from 声明的起始端点的 URI 中,flowable 为协议开头,CamelTaskProcess 为流程定义 key,
camelTask1 为 Camel 任务 id,输入参数配置的 copyVariablesToProperties=true 表示将 Activiti 的流程
变量复制成 Camel 参数,输出参数使用的默认配置。
⑵终止端点采用 toD 声明,它允许通过表达式的方式来动态定义消息的接收节点,这里使用了
表达式${property.ip},表示从 Camel 参数中获取 ip 属性的值。
⑶路由中使用到了自定义 Processor 处理器 ResultProcessor。Processor 处理器是 Camel 中的一
个重要元素,它用于接收从控制端点、路由选择条件又或者另一个处理器的 Exchange 中传来的消
息信息,并进行处理。我们可以在自定义的 Processor 处理器中做很多事情,比如这里使用它来进
行外部服务返回结果数据格式的转换,代码如下
import com.alibaba.fastjson.JSON;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import java.util.Map;
import java.util.stream.Collectors;
public class ResultProcessor implements Processor {public void process(Exchange exchange) {// camelString camelCallResult =exchange.getIn().getBody(String.class);// camelSystem.out.println("camel" + camelCallResult);// MapMap<String, String> camelCallResultMap = JSON.parseObject(camelCallResult,Map.class);//Map<String, String> resultMap =camelCallResultMap.entrySet().stream().filter(map -> "country".equals(map.getKey()) ||"regionName".equals(map.getKey())|| "city".equals(map.getKey()) ||"isp".equals(map.getKey())).collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue));// Camel Mapexchange.getOut().setBody(resultMap, Map.class);}
}
在以上代码中,首先获取访问外部服务返回的结果(是一个 json 字符串),然后将其转成 Map
对象,接下来对其 key 进行过滤仅保留 country、regionName、city 和 isp 组成一个新的 Map,最后
将该 Map 作为 Camel 消息体回传给 Flowable。
视频地址:
骆驼任务
相关文章:
Flowable-服务-骆驼任务
目录 定义图形标记XML内容Flowable与Camel集成使用示例设计Came路由代码 定义 Camel 任务不是 BPMN 2.0 规范定义的官方任务,在 Flowable 中,Camel 任务是作为一种特殊的服务 任务来实现的。主要做路由工作的。 图形标记 由于 Camel 任务不是 BPMN 2.…...
用html+javascript打造公文一键排版系统9:主送机关排版
一、主送机关的规定 公文一般在标题和正文之间还有主送机关,相关规定为: 主送机关 编排于标题下空一行位置,居左顶格,回行时仍顶格,最后一个机关名称后标全角冒号。如主送机关名称过多导致公文首页不能显示正文时&…...
SpringBoot 集成 EasyExcel 3.x 优雅实现 Excel 导入导出
介绍 EasyExcel 是一个基于 Java 的、快速、简洁、解决大文件内存溢出的 Excel 处理工具。它能让你在不用考虑性能、内存的等因素的情况下,快速完成 Excel 的读、写等功能。 EasyExcel文档地址: https://easyexcel.opensource.alibaba.com/ 快速开始 …...
RT1052 的四定时器
文章目录 1 Quad Timer,简称:QTMR2 单个通道的框图3 QTMR配置3.1 QTMR1 时钟使能。3.2 初始化 QTMR1。3.2.1 QTMR_Init 3.3 设置 QTMR1 通道 0 的定时周期。3.3.1QTMR_SetTimerPeriod 3.4 使能 QTMR1 通道 0 的比较中断。3.4.1 QTMR_EnableInterrupts 3.…...
ViT-vision transformer
ViT-vision transformer 介绍 Transformer最早是在NLP领域提出的,受此启发,Google将其用于图像,并对分类流程作尽量少的修改。 起源:从机器翻译的角度来看,一个句子想要翻译好,必须考虑上下文的信息&…...
Election of the King 2023牛客暑期多校训练营4-F
登录—专业IT笔试面试备考平台_牛客网 题目大意:有一个n个数的数组a,有n-1轮操作,每轮由每个数选择一个和它的差最大的数,如果相同就选值更大的,被最多数组选择的数字被删去,有相同的也去掉数值更大的那个…...
Nacos的搭建及服务调用
文章目录 一、搭建Nacos服务1、Nacos2、安装Nacos3、Docker安装Nacos 二、OpenFeign和Dubbo远程调用Nacos的服务1、搭建SpringCloudAlibaba的开发环境1.1 构建微服务聚合父工程1.2 创建子模块cloud-provider-payment80011.3 创建子模块cloud-consumer-order80 2、远程服务调用O…...
uniapp小程序自定义loding,通过状态管理配置全局使用
一、在项目中创建loding组件 在uniapp的components文件夹下创建loding组件,如图: 示例代码: <template><view class"loginLoading"><image src"../../static/loading.gif" class"loading-img&q…...
leetcode 45. 跳跃游戏 II
2023.7.30 class Solution { public:int jump(vector<int>& nums) {int step 0;int cover 0;int largest 0;if(nums.size() 1) return step;for(int i0; i<nums.size(); i){cover max(cover , inums[i]); //最大覆盖范围if(cover > nums.size()-1) retur…...
力扣热门100题之矩阵置0【中等】
题目描述 给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1: 输入:matrix [[1,1,1],[1,0,1],[1,1,1]] 输出:[[1,0,1],[0,0,0],[1,0,1]] 示例 2ÿ…...
【机器学习】Classification using Logistic Regression
Classification using Logistic Regression 1. 分类问题2. 线性回归方法3. 逻辑函数(sigmod)4.逻辑回归5. 决策边界5.1 数据集5.2 数据绘图5.3 逻辑回归与决策边界的刷新5.4 绘制决策边界 导入所需的库 import numpy as np %matplotlib widget import m…...
全方位支持图文和音视频、100+增强功能,Facebook开源数据增强库AugLy
Facebook 近日开源了数据增强库 AugLy,包含四个子库,每个子库对应不同的模态,每个库遵循相同的接口。支持四种模态:文本、图像、音频和视频。 最近,Facebook 开源了一个新的 Python 库——AugLy,该库旨在帮…...
RxSwift 使用方式
背景 最近项目业务,所有模块已经支持Swift混编开发,正在逐步使用Swift 方式进行开发新业务,以及逐步替换老业务方式进行发展,所以使用一些较为成熟的Swift 的三方库,成为必要性,经过调研发现RxSwift 在使用…...
HTML5 Web Worker
HTML5 Web Worker是一种浏览器提供的JavaScript多线程解决方案,它允许在后台运行独立于页面主线程的脚本,从而避免阻塞页面的交互和渲染。Web Worker可以用于执行计算密集型任务、处理大量数据、实现并行计算等,从而提升前端应用的性能和响应…...
25.9 matlab里面的10中优化方法介绍—— 惩罚函数法求约束最优化问题(matlab程序)
1.简述 一、算法原理 1、问题引入 之前我们了解过的算法大部分都是无约束优化问题,其算法有:黄金分割法,牛顿法,拟牛顿法,共轭梯度法,单纯性法等。但在实际工程问题中,大多数优化问题都属于有约…...
django channels实战(websocket底层原理和案例)
1、websocket相关 1.1、轮询 1.2、长轮询 1.3、websocket 1.3.1、websocket原理 1.3.2、django框架 asgi.py在django项目同名app目录下 1.3.3、聊天室 django代码总结 小结 1.3.4、群聊(一) 前端代码 后端代码 1.3.5、群聊(二)…...
学习使用axios,绑定动态数据
目录 axios特性 案例一:通过axios获取笑话 案例二:调用城市天气api接口数据实现天气查询案例 axios特性 支持 Promise API 拦截请求和响应(可以在请求前及响应前做某些操作,例如,在请求前想要在这个请求头中加一些…...
c语言内存函数的深度解析
本章对 memcpy,memmove,memcmp 三个函数进行详解和模拟实现; 本章重点:3个常见内存函数的使用方法及注意事项并学会模拟实现; 如果您觉得文章不错,期待你的一键三连哦,你的鼓励是我创作的动力…...
低代码平台介绍(国内常见的)
文章目录 前言1、阿里云宜搭2、腾讯云微搭3、百度爱速搭4、华为云Astro轻应用 Astro Zero(AppCube)5、字节飞书多维表格6、云程低代码平台7、ClickPaaS8、网易轻舟9、用友YonBuilder10、金蝶苍穹云平台11、泛微平台12、蓝凌低代码平台13、简道云14、轻流…...
matlab RRR机械臂 简略代码
RRR机器人!启动! gazebo在arm mac上似乎难以运行,退而选择Matlab,完成老师第一个作业,现学现卖,权当记录作业过程,有不足之处,多多指教。 作业!启动! RRR机…...
多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...
css的定位(position)详解:相对定位 绝对定位 固定定位
在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...
如何应对敏捷转型中的团队阻力
应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中,明确沟通敏捷转型目的尤为关键,团队成员只有清晰理解转型背后的原因和利益,才能降低对变化的…...
在 Spring Boot 中使用 JSP
jsp? 好多年没用了。重新整一下 还费了点时间,记录一下。 项目结构: pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...
