1、Flowable基础

Flowable是BPMN的一个基于java的软件实现,不过Flowable不仅仅包括BPMN,还有DMN决策表和CMMN Case管理引擎,并且有自己的用户管理、微服务API等一系列功能,是一个服务平台。

官方手册:https://tkjohn.github.io/flowable-userguide/#_introduction

1.创建ProcessEngine

  创建一个基本的maven工程,可以是Eclipse也可以是其他IDEA。然后添加两个依赖

  • Flowable流程引擎。使我们可以创建一个ProcessEngine流程引擎对象,并访问Flowable API。
  • 一个是MySQL的数据库驱动

pom.xml文件中添加下列行:

<dependency><groupId>org.flowable</groupId><artifactId>flowable-engine</artifactId><version>6.3.0</version>
</dependency>
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.21</version>
</dependency>

然后创建一个普通的Java类,添加对应的main方法,首先要做的是初始化ProcessEngine流程引擎实例。这是一个线程安全的对象,因此通常只需要在一个应用中初始化一次。 ProcessEngineProcessEngineConfiguration实例创建。该实例可以配置与调整流程引擎的设置。 通常使用一个配置XML文件创建ProcessEngineConfiguration,但是(像在这里做的一样)也可以编程方式创建它。 ProcessEngineConfiguration所需的最小配置,是数据库JDBC连接:

public static void main(String[] args) {ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration().setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn?serverTimezone=UTC").setJdbcUsername("root").setJdbcPassword("123456").setJdbcDriver("com.mysql.cj.jdbc.Driver").setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);ProcessEngine processEngine = cfg.buildProcessEngine();
}

注意在mysql8.0中执行可能出现如下的错误
在这里插入图片描述
出现这种情况只需要在mysql的连接字符串中添加上nullCatalogMeansCurrent=true,设置为只查当前连接的schema库即可。

 public static void main(String[] args) {ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration().setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn1?serverTimezone=UTC&nullCatalogMeansCurrent=true").setJdbcUsername("root").setJdbcPassword("123456").setJdbcDriver("com.mysql.cj.jdbc.Driver").setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);ProcessEngine processEngine = cfg.buildProcessEngine();}

然后应用运行没有问题,但也没有在控制台提供有用的信息,只有一条消息提示日志没有正确配置。Flowable使用SLF4J作为内部日志框架。在这个例子中,我们使用log4j作为SLF4J的实现。因此在pom.xml文件中添加下列依赖:

<dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.21</version>
</dependency>
<dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>1.7.21</version>
</dependency>

Log4j需要一个配置文件。在src/main/resources文件夹下添加log4j.properties文件,并写入下列内容:

log4j.rootLogger=DEBUG, CAlog4j.appender.CA=org.apache.log4j.ConsoleAppender
log4j.appender.CA.layout=org.apache.log4j.PatternLayout
log4j.appender.CA.layout.ConversionPattern= %d{hh:mm:ss,SSS} [%t] %-5p %c %x - %m%n

重新运行应用。应该可以看到关于引擎启动与创建数据库表结构的提示日志:
在这里插入图片描述
同时可以看到创建了相关的表结构在数据库中
在这里插入图片描述

2.部署流程定义

  接下来我们构建一个非常简单的请假流程,Flowable引擎需要流程定义为BPMN 2.0格式,这是一个业界广泛接受的XML标准。 在Flowable术语中,我们将其称为一个流程定义(process definition)。一个流程定义可以启动多个流程实例(process instance)流程定义可以看做是重复执行流程的蓝图。 在这个例子中,流程定义定义了请假的各个步骤,而一个流程实例对应某个雇员提出的一个请假申请。

  BPMN 2.0存储为XML,并包含可视化的部分:使用标准方式定义了每个步骤类型(人工任务,自动服务调用,等等)如何呈现,以及如何互相连接。这样BPMN 2.0标准使技术人员与业务人员能用双方都能理解的方式交流业务流程。

我们要使用的流程定义为:
在这里插入图片描述
  流程定义说明:

  • 我们假定启动流程需要提供一些信息,例如雇员名字、请假时长以及说明。当然,这些可以单独建模为流程中的第一步。 但是如果将它们作为流程的“输入信息”,就能保证只有在实际请求时才会建立一个流程实例。否则(将提交作为流程的第一步),用户可能在提交之前改变主意并取消,但流程实例已经创建了。 在某些场景中,就可能影响重要的指标(例如启动了多少申请,但还未完成),取决于业务目标。
  • 左侧的圆圈叫做启动事件(start event)。这是一个流程实例的起点。
  • 第一个矩形是一个用户任务(user task)。这是流程中用户操作的步骤。在这个例子中,经理需要批准或驳回申请
  • 取决于经理的决定,排他网关(exclusive gateway) (带叉的菱形)会将流程实例路由至批准或驳回路径
  • 如果批准,则需要将申请注册至某个外部系统,并跟着另一个用户任务,将经理的决定通知给申请人。当然也可以改为发送邮件。
  • 如果驳回,则为雇员发送一封邮件通知他。

 一般来说,这样的流程定义使用可视化建模工具建立,如Flowable Designer(Eclipse)或Flowable Web Modeler(Web应用)。但在这里我们直接撰写XML,以熟悉BPMN 2.0及其概念。

  与上面展示的流程图对应的BPMN 2.0 XML在下面显示。请注意这只包含了“流程部分”。如果使用图形化建模工具,实际的XML文件还将包含“可视化部分”,用于描述图形信息,如流程定义中各个元素的坐标(所有的图形化信息包含在XML的BPMNDiagram标签中,作为definitions标签的子元素)。

  将下面的XML保存在src/main/resources文件夹下名为holiday-request.bpmn20.xml的文件中。

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"xmlns:flowable="http://flowable.org/bpmn"typeLanguage="http://www.w3.org/2001/XMLSchema"expressionLanguage="http://www.w3.org/1999/XPath"targetNamespace="http://www.flowable.org/processdef"><process id="holidayRequest" name="Holiday Request" isExecutable="true"><startEvent id="startEvent"/><sequenceFlow sourceRef="startEvent" targetRef="approveTask"/><userTask id="approveTask" name="Approve or reject request"/><sequenceFlow sourceRef="approveTask" targetRef="decision"/><exclusiveGateway id="decision"/><sequenceFlow sourceRef="decision" targetRef="externalSystemCall"><conditionExpression xsi:type="tFormalExpression"><![CDATA[${approved}]]></conditionExpression></sequenceFlow><sequenceFlow  sourceRef="decision" targetRef="sendRejectionMail"><conditionExpression xsi:type="tFormalExpression"><![CDATA[${!approved}]]></conditionExpression></sequenceFlow><serviceTask id="externalSystemCall" name="Enter holidays in external system"flowable:class="org.flowable.CallExternalSystemDelegate"/><sequenceFlow sourceRef="externalSystemCall" targetRef="holidayApprovedTask"/><userTask id="holidayApprovedTask" name="Holiday approved"/><sequenceFlow sourceRef="holidayApprovedTask" targetRef="approveEnd"/><serviceTask id="sendRejectionMail" name="Send out rejection email"flowable:class="org.flowable.SendRejectionMail"/><sequenceFlow sourceRef="sendRejectionMail" targetRef="rejectEnd"/><endEvent id="approveEnd"/><endEvent id="rejectEnd"/></process></definitions>

  现在我们已经有了流程BPMN 2.0 XML文件,下来需要将它部署(deploy)到引擎中。部署一个流程定义意味着:

  • 流程引擎会将XML文件存储在数据库中,这样可以在需要的时候获取它
  • 流程定义转换为内部的、可执行的对象模型,这样使用它就可以启动流程实例

在这里插入图片描述
 将流程定义部署至Flowable引擎,需要使用RepositoryService,其可以从ProcessEngine对象获取。使用RepositoryService,可以通过XML文件的路径创建一个新的部署(Deployment),并调用*deploy()*方法实际执行:

 /*** 部署流程*/@Testpublic void testDeploy(){// 配置数据库相关信息 获取 ProcessEngineConfigurationProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration().setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn2?serverTimezone=UTC&nullCatalogMeansCurrent=true").setJdbcUsername("root").setJdbcPassword("123456").setJdbcDriver("com.mysql.cj.jdbc.Driver").setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);// 获取流程引擎对象ProcessEngine processEngine = cfg.buildProcessEngine();// 部署流程 获取RepositoryService对象RepositoryService repositoryService = processEngine.getRepositoryService();Deployment deployment = repositoryService.createDeployment()// 创建Deployment对象.addClasspathResource("holiday-request.bpmn20.xml") // 添加流程部署文件.name("请求流程") // 设置部署流程的名称.deploy(); // 执行部署操作System.out.println("deployment.getId() = " + deployment.getId());System.out.println("deployment.getName() = " + deployment.getName());}

然后执行该方法日志操作成功:
在这里插入图片描述
在后台表结构也可以看到相关的信息

act_re_deployment: 流程定义部署表,每部署一次就增加一条记录
在这里插入图片描述
act_re_procdef :流程定义表,部署每个新的流程定义都会在这张表中增加一条记录

在这里插入图片描述
act_ge_bytearray :流程资源表,流程部署的 bpmn文件和png图片会保存在该表中
在这里插入图片描述
我们现在可以通过API查询验证流程定义已经部署在引擎中(并学习一些API)。通过RepositoryService创建的ProcessDefinitionQuery对象实现。

/*** 查看流程定义*/@Testpublic void testDeployQuery(){// 配置数据库相关信息 获取 ProcessEngineConfigurationProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration().setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn2?serverTimezone=UTC&nullCatalogMeansCurrent=true").setJdbcUsername("root").setJdbcPassword("123456").setJdbcDriver("com.mysql.cj.jdbc.Driver").setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);// 获取流程引擎对象ProcessEngine processEngine = cfg.buildProcessEngine();// 部署流程 获取RepositoryService对象RepositoryService repositoryService = processEngine.getRepositoryService();// 获取流程定义对象ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId("2501").singleResult();System.out.println("processDefinition.getId() = " + processDefinition.getId());System.out.println("processDefinition.getName() = " + processDefinition.getName());System.out.println("processDefinition.getDeploymentId() = " + processDefinition.getDeploymentId());System.out.println("processDefinition.getDescription() = " + processDefinition.getDescription());}

输出结果为:

processDefinition.getId() = holidayRequest:2:2503
processDefinition.getName() = Holiday Request
processDefinition.getDeploymentId() = 2501
processDefinition.getDescription() = null

3.启动流程实例

  现在已经在流程引擎中部署了流程定义,因此可以使用这个流程定义作为“模板”启动流程实例

在这里插入图片描述
要启动流程实例,需要提供一些初始化流程变量。一般来说,可以通过呈现给用户的表单,或者在流程由其他系统自动触发时通过REST API,来获取这些变量。在这个例子里,我们简化直接在代码中定义了,我们使用RuntimeService启动一个流程实例

  /*** 启动流程实例*/@Testpublic void testRunProcess(){// 配置数据库相关信息 获取 ProcessEngineConfigurationProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration().setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn2?serverTimezone=UTC&nullCatalogMeansCurrent=true").setJdbcUsername("root").setJdbcPassword("123456").setJdbcDriver("com.mysql.cj.jdbc.Driver").setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);// 获取流程引擎对象ProcessEngine processEngine = cfg.buildProcessEngine();// 启动流程实例通过 RuntimeService 对象RuntimeService runtimeService = processEngine.getRuntimeService();// 构建流程变量Map<String,Object> variables = new HashMap<>();variables.put("employee","张三") ;// 谁申请请假variables.put("nrOfHolidays",3); // 请几天假variables.put("description","工作累了,想出去玩玩"); // 请假的原因// 启动流程实例,第一个参数是流程定义的idProcessInstance processInstance = runtimeService.startProcessInstanceByKey("holidayRequest", variables);// 启动流程实例// 输出相关的流程实例信息System.out.println("流程定义的ID:" + processInstance.getProcessDefinitionId());System.out.println("流程实例的ID:" + processInstance.getId());System.out.println("当前活动的ID:" + processInstance.getActivityId());}

启动成功,输出结果如下:

流程定义的ID:holidayRequest:2:2503
流程实例的ID5001
当前活动的IDnull

对应的流程实例ID为:5001

启动流程实例涉及到的表结构:

  • act_hi_actinst 流程实例执行历史
  • act_hi_identitylink 流程的参与用户的历史信息
  • act_hi_procinst 流程实例历史信息
  • act_hi_taskinst 流程任务历史信息
  • act_ru_execution 流程执行信息
  • act_ru_identitylink 流程的参与用户信息
  • act_ru_task 任务信息

4.查看任务

  上面员工发起了一个请假流程,接下来就会流转到总经理这儿来处理,之前我们没有指定经理这的处理人,我们可以加一个

在这里插入图片描述
  然后我们来查看下lisi的任务

   /*** 查看任务*/@Testpublic void testQueryTask(){// 配置数据库相关信息 获取 ProcessEngineConfigurationProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration().setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn2?serverTimezone=UTC&nullCatalogMeansCurrent=true").setJdbcUsername("root").setJdbcPassword("123456").setJdbcDriver("com.mysql.cj.jdbc.Driver").setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);// 获取流程引擎对象ProcessEngine processEngine = cfg.buildProcessEngine();TaskService taskService = processEngine.getTaskService();List<Task> list = taskService.createTaskQuery().processDefinitionKey("holidayRequestNew").taskAssignee("lisi").list();for (Task task : list) {System.out.println("task.getProcessDefinitionId() = " + task.getProcessDefinitionId());System.out.println("task.getId() = " + task.getId());System.out.println("task.getAssignee() = " + task.getAssignee());System.out.println("task.getName() = " + task.getName());}}

输出结果为:

task.getProcessDefinitionId() = holidayRequestNew:1:10003
task.getId() = 12508
task.getAssignee() = lisi
task.getName() = Approve or reject request

5.完成任务

  现在李四这个角色可以来完成当前的任务了

在这里插入图片描述
 在此处我们直接解决掉这个请假,然后会走发送拒绝邮件的流程,这块我们需要用到JavaDelegate来触发。

我们定义这样一个Java类

public class SendRejectionMail implements JavaDelegate {/*** 触发发送邮件的操作* @param delegateExecution*/@Overridepublic void execute(DelegateExecution delegateExecution) {System.out.println("请假被拒绝,,,安心工作吧");}
}

然后来完成任务

 /*** 完成任务*/@Testpublic void testCompleteTask(){// 配置数据库相关信息 获取 ProcessEngineConfigurationProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration().setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn2?serverTimezone=UTC&nullCatalogMeansCurrent=true").setJdbcUsername("root").setJdbcPassword("123456").setJdbcDriver("com.mysql.cj.jdbc.Driver").setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);// 获取流程引擎对象ProcessEngine processEngine = cfg.buildProcessEngine();TaskService taskService = processEngine.getTaskService();Task task = taskService.createTaskQuery().processDefinitionKey("holidayRequestNew").taskAssignee("lisi").singleResult();// 添加流程变量Map<String,Object> variables = new HashMap<>();variables.put("approved",false); // 拒绝请假// 完成任务taskService.complete(task.getId(),variables);}

然后可以看到JavaDelegate触发了
在这里插入图片描述

6.流程的删除

  有些流程已经没有用了,我们需要删除掉,其实也非常简单

  /*** 删除流程*/@Testpublic void testDeleteProcess(){// 配置数据库相关信息 获取 ProcessEngineConfigurationProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration().setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn2?serverTimezone=UTC&nullCatalogMeansCurrent=true").setJdbcUsername("root").setJdbcPassword("123456").setJdbcDriver("com.mysql.cj.jdbc.Driver").setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);// 获取流程引擎对象ProcessEngine processEngine = cfg.buildProcessEngine();RepositoryService repositoryService = processEngine.getRepositoryService();// 删除流程定义,如果该流程定义已经有了流程实例启动则删除时报错// repositoryService.deleteDeployment("1");// 设置为TRUE 级联删除流程定义,及时流程有实例启动,也可以删除,设置为false 非级联删除操作。repositoryService.deleteDeployment("2501",true);}

7.查看历史信息

  选择使用Flowable这样的流程引擎的原因之一,是它可以自动存储所有流程实例的审计数据历史数据。这些数据可以用于创建报告,深入展现组织运行的情况,瓶颈在哪里,等等。

  例如,如果希望显示流程实例已经执行的时间,就可以从ProcessEngine获取HistoryService,并创建*历史活动(historical activities)*的查询。在下面的代码片段中,可以看到我们添加了一些额外的过滤条件:

  • 只选择一个特定流程实例的活动
  • 只选择已完成的活动

  结果按照结束时间排序,代表其执行顺序。

/*** 查看历史*/@Testpublic void testQueryHistory(){// 配置数据库相关信息 获取 ProcessEngineConfigurationProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration().setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn2?serverTimezone=UTC&nullCatalogMeansCurrent=true").setJdbcUsername("root").setJdbcPassword("123456").setJdbcDriver("com.mysql.cj.jdbc.Driver").setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);// 获取流程引擎对象ProcessEngine processEngine = cfg.buildProcessEngine();HistoryService historyService = processEngine.getHistoryService();List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery().processDefinitionId("holidayRequestNew:1:10003").finished().orderByHistoricActivityInstanceEndTime().asc().list();for (HistoricActivityInstance historicActivityInstance : list) {System.out.println(historicActivityInstance.getActivityId() + " took "+ historicActivityInstance.getDurationInMillis() + " milliseconds");}}

输出结果

startEvent took 1 milliseconds
approveTask took 837735 milliseconds
decision took 13 milliseconds
sendRejectionMail took 2 milliseconds
rejectEnd took 1 milliseconds

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/162988.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

推荐系统离线评估方法和评估指标,以及在推荐服务器内部实现A/B测试和解决A/B测试资源紧张的方法。还介绍了如何在TensorFlow中进行模型离线评估实践。

文章目录 &#x1f31f; 离线评估&#xff1a;常用的推荐系统离线评估方法有哪些&#xff1f;&#x1f34a; 1. RMSE/MSE&#x1f34a; 2. MAE&#x1f34a; 3. Precision/Recall/F1-score&#x1f34a; 4. Coverage&#x1f34a; 5. Personalization&#x1f34a; 6. AUC &…

Spring Security登录账户自定义与数据持久化(5)

1、用户自定义 在前面的案例中&#xff0c;我们的登录用户是基于配置文件来配置的(本质是基于内存)&#xff0c;但是在实际开发中&#xff0c;这种方式肯定是不可取的&#xff0c;在实际项目中&#xff0c;用户信息肯定要存入数据库之中。 Spring Security支持多种用户定义方…

和鲸ModelWhale与中科可控X系列异构加速服务器完成适配认证,搭载海光芯片,构筑AI算力底座

AIGC 时代&#xff0c;算力作为新型生产力&#xff0c;是国家和企业构建竞争优势的关键。而随着传统计算方式无法满足新时代激增的算力需求&#xff0c;计算场景的多元化和计算应用的复杂化推动了 CPUGPU 异构平台的加速组建。在此全球激烈角逐的大趋势下&#xff0c;我国信创产…

《论文阅读28》OGMM

一、论文 研究领域&#xff1a; 点云配准 | 有监督 部分重叠论文&#xff1a;Overlap-guided Gaussian Mixture Models for Point Cloud Registration WACV 2023 二、概述 概率3D点云配准方法在克服噪声、异常值和密度变化方面表现出有竞争力的性能。本文将点云对的配准问题…

腾讯云服务器带宽下载速度表(附上行带宽计算方法)

腾讯云服务器公网带宽下载速度计算&#xff0c;1M公网带宽下载速度是128KB/秒&#xff0c;5M带宽下载速度是512KB/s&#xff0c;腾讯云10M带宽下载速度是1.25M/秒&#xff0c;腾讯云百科txybk.com来详细说下腾讯云服务器不同公网带宽实际下载速度以及对应的上传速度对照表&…

凉鞋的 Unity 笔记 202. 变量概述与简介

202. 变量概述与简介 想要用好变量不是一件简单的事情&#xff0c;因为变量需要命名。 我们可以从两个角度看待一个变量&#xff0c;第一个角度是变量的功能&#xff0c;第二个是变量的可读性。 变量的功能其实非常简单&#xff0c;变量可以存储一个值&#xff0c;这个值是特…

Flume 简介及基本使用

1.Flume简介 Apache Flume 是一个分布式,高可用的数据收集系统。它可以从不同的数据源收集数据,经过聚合后发送到存储系统中,通常用于日志数据的收集。Flume 分为 NG 和 OG (1.0 之前) 两个版本,NG 在 OG 的基础上进行了完全的重构,是目前使用最为广泛的版本。下面的介绍均…

创建node、vue、以及@vuecli 和 vue-cli 的区别

创建node、vue、以及vue/cli 和 vue-cli 的区别 创建vue的五种方法 参考 如何创建一个vue项目&#xff08;详细步骤&#xff09; 方法一&#xff1a;vue init webpack 项目名&#xff08;vue-cli2.x的初始化方式&#xff09; vue init webpack blog 创建项目(blog 是项目名…

疯狂堆料!技嘉钛雕Z790 AORUS PRO X主板图赏

技嘉推出了钛雕Z790 AORUS PRO X主板。 现在这款新品已经来到了我们评测室&#xff0c;下面为大家带来图赏。 技嘉钛雕Z790 AORUS PRO X主板采用新一代超耐久显卡插槽&#xff0c;约58KG承重能力、内衬保护显卡PCB。 其采用1812相供电设计&#xff0c;4根双通道DDR5内存插槽&am…

开源情报之领英人脸情报收集,如何快速收集上亿张人脸情报

一.前言 先看应用例子&#xff1a; 残忍至极&#xff01;乌克兰用人脸识别战死俄军&#xff0c;联系母亲打“心理战” 情报机构&#xff0c;所掌握的数据&#xff0c;可以是市面上流出的任何数据&#xff0c;比如市面上泄露的领英数据&#xff0c;facebook&#xff0c;twitter&…

Kylin麒麟系统下安装人大金仓

虚拟机在线安装 install open-vm-tools-desktop -y 简要介绍 人大金仓数据库管理系统KingbaseES&#xff08;简称&#xff1a;金仓数据库或KingbaseES&#xff09;是北京人大金仓信息技术股份有限公司自主研制开发的具有自主知识产权的通用关系型数据库管理系统。金仓数据库主…

YOLOv7改进:动态蛇形卷积(Dynamic Snake Convolution),增强细微特征对小目标友好,实现涨点 | ICCV2023

💡💡💡本文独家改进:动态蛇形卷积(Dynamic Snake Convolution),增强细长微弱的局部结构特征与复杂多变的全局形态特征,对小目标检测很适用 Dynamic Snake Convolution | 亲测在多个数据集能够实现大幅涨点 收录: YOLOv7高阶自研专栏介绍: http://t.csdnimg.…

Operator 开发实践 四 (WebHook)

1. WebHook介绍 我们知道访问Kubernetes API有好几种方式&#xff0c;比如使用kubectl命令、使用client-go之类的开发库、直接通过REST请求等。不管是一个使用kubectl的真人用户&#xff0c;还是一个Service Account&#xff0c;都可以通过API访问认证&#xff0c;这个过程官网…

【Java学习之道】JDBC API介绍与使用方法

引言 对于初学者来说&#xff0c;数据库编程可能听起来有些复杂&#xff0c;但实际上&#xff0c;只要你掌握了JDBC&#xff08;Java Database Connectivity&#xff09;API&#xff0c;就可以轻松地连接和操作数据库。本章将为你详细介绍JDBC API的概念、使用方法以及一些实际…

zabbix触发器与动作

一、触发器&#xff08;Trigger&#xff09; 1、概念&#xff1a; 在 Zabbix 中&#xff0c;触发器用于监测 Zabbix 监控系统中的各种指标和条件&#xff0c;并在特定条件满足时触发警报。&#xff08;触发器用于定义监控项的报警阈值&#xff09; 2、触发器对象&#xff1a…

chatglm配置

推荐看这个链接&#xff0c;有些问题解决出处https://zhuanlan.zhihu.com/p/643824521 以及这个https://blog.csdn.net/weixin_40547993/article/details/131775275 1.需要pytorch2.0&#xff0c;所以CUDA推荐11.8 ChatGLM2-6B版本要装PYTORCH2.0&#xff0c;而且要2.0.1 &a…

檀香香料经营商城小程序的作用是什么

檀香香料有安神、驱蚊、清香等作用&#xff0c;办公室或家庭打坐等场景&#xff0c;都有较高的使用频率&#xff0c;不同香料也有不同效果&#xff0c;高品质香料檀香也一直受不少消费者欢迎。 线下流量匮乏&#xff0c;又难以实现全消费路径完善&#xff0c;线上是商家增长必…

Python|Pyppeteer获取去哪儿酒店数据(20)

前言 本文是该专栏的第20篇,结合优质项目案例持续分享Pyppeteer的干货知识,记得关注。 本文以去哪儿为例,笔者将详细介绍使用pyppeteer获取去哪儿的酒店数据。如果对pyppeteer的使用以及知识点不太熟悉的同学,可往前查看本专栏前面介绍的pyppeteer知识点。 接下来,我们言…

web前端基础CSS------美化页面“footer”部分

一&#xff0c;实验代码 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>关于我们</title><style type"text/css">#footer{margin: 10px 0px;background: #f5f5f5;border: top 1px solid #eee ;}#f…

Electron webview 内网页 与 preload、 渲染进程、主进程的常规通信 以及企业级开发终极简化通信方式汇总

Electron 嵌入的页面中注入的是 preload.js 通过在标签中给 prelaod赋值&#xff0c;这里提到了 file://前缀&#xff0c;以及静态目录 static 怎么获取 实际代码&#xff0c;其中__static就是我们存放静态文件的地方&#xff0c;这个 static 是 electron 源代码根目录下的文件…