flowable实战(四):构建命令行程序

2023-11-10

实际上前面那些都是前置知识,真正上手的话其实还是一脸懵的情况,这里我也是按照文档生成一个最简单的demo。这个demo就是一个简单的Maven工程,你只要启动main方法就可以看到效果。

github实例代码地址

这里如果直接下载代码,如果不熟悉maven的话可能不能直接上手用。其实不需要多做什么,直接点击对应的SimpleDemo下面的pom文件,点击右键找到“add maven xxx”的就可以了,转化成maven工程就可以直接上手用了。

当然也可以根据文档或者我们下面的步骤一部接一部的来
文档对应的地址
flowable构建命令行程序

一创建一个maven工程的flowable命令行程序
创建一个maven工程,这个就不赘述了,文档还有其他关于如何创建的maven工程的文章也很多,一搜一大把。

maven主要还是需要解决他的pom文件里面的依赖,这我直接贴完整的

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>flowable-test</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.flowable</groupId>
            <artifactId>flowable-engine</artifactId>
            <version>6.7.2</version>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.3.176</version>
        </dependency>
        <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>

<!--       这个其实也可以替代上面两个slf4j设置-->
<!--        <dependency>-->
<!--            <groupId>org.slf4j</groupId>-->
<!--            <artifactId>slf4j-simple</artifactId>-->
<!--            <version>1.7.21</version>-->
<!--            <scope>compile</scope>-->
<!--        </dependency>-->
    </dependencies>


    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

</project>

这里slf4j是因为flowable需要的,所以也是需要添加对应的依赖。

当然它对应的日志配置文件log4j.properties

log4j.rootLogger=DEBUG, CA

log4j.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

再加一个main方法作为demo的入口

package org.flowable;

public class HolidayRequest {

  public static void main(String[] args) {

  }

}

二 创建流程引擎
初始化ProcessEngine流程引擎实例,类似于MySQL的innoDB,系统处理的核心部分。

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

这里用的代码直接配置数据库就不管了,最简单那的种。

 ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration()
      .setJdbcUrl("jdbc:h2:mem:flowable;DB_CLOSE_DELAY=-1")
      .setJdbcUsername("sa")
      .setJdbcPassword("")
      .setJdbcDriver("org.h2.Driver")
      .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);

    ProcessEngine processEngine = cfg.buildProcessEngine();

二 部署流程定义
构建的流程是一个非常简单的请假流程。Flowable引擎需要流程定义为BPMN 2.0格式。大部分我们还都是画图直接画的,像平时干脆直接那别的流程改一改,作为一个新的流程。

画的图背后实际还是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>

三部署流程

这里有一个词deploy,除了部署(deploy)到引擎中,对应的方法也叫deploy()

部署一个流程定义意味着:

流程引擎会将XML文件存储在数据库中,这样可以在需要的时候获取它。

流程定义转换为内部的、可执行的对象模型,这样使用它就可以启动流程实例。

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

四 启动流程实例

有流程了,只是定义了一个而已,实际上我们工作流要的是一个个“审批”,这就是根据流程定义得到的流程实例。

要启动流程实例,需要提供一些初始化流程变量。一般来说,可以通过呈现给用户的表单,或者在流程由其他系统自动触发时通过REST API,来获取这些变量。在这个例子里,我们简化为使用java.util.Scanner类在命令行输入一些数据。

Scanner scanner= new Scanner(System.in);

System.out.println("Who are you?");
String employee = scanner.nextLine();

System.out.println("How many holidays do you want to request?");
Integer nrOfHolidays = Integer.valueOf(scanner.nextLine());

System.out.println("Why do you need them?");
String description = scanner.nextLine();

启动的实例,这边是根据key,这里是holidayRequest。

  <process id="holidayRequest" name="Holiday Request" isExecutable="true">

        <startEvent id="startEvent"/>
        <sequenceFlow sourceRef="startEvent" targetRef="approveTask"/>

        <userTask id="approveTask" name="Approve or reject request" flowable:candidateGroups="managers"/>
        <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>

参这XML文件使用key启动(实际上还有别的方式)

RuntimeService runtimeService = processEngine.getRuntimeService();

Map<String, Object> variables = new HashMap<String, Object>();
variables.put("employee", employee);
variables.put("nrOfHolidays", nrOfHolidays);
variables.put("description", description);
ProcessInstance processInstance =
  runtimeService.startProcessInstanceByKey("holidayRequest", variables);

五 事务
Flowable中,数据库事务扮演了关键角色,用于保证数据一致性,并解决并发问题。
当调用Flowable API时,默认情况下,所有操作都是同步的,并处于同一个事务下。这意味着,当方法调用返回时,会启动并提交一个事务。

在Flowable中,当一个流程实例运行时,总会有一个数据库事务从前一个等待状态持续到下一个等待状态。数据持久化之后,可能在数据库中保存很长时间,甚至几年,直到某个API调用使流程实例继续执行。请注意当流程处在等待状态时,不会消耗任何计算或内存资源,直到下一次APi调用。

六 查询与完成任务
查看任务列表。其中可以看到作为流程变量存储的流程实例数据,并决定如何操作任务。在这个例子中,我们通过执行API调用来模拟任务列表,通常这些API都是由UI驱动的服务在后台调用的。

用户任务candidateGroups属性

为用户任务配置办理人。我们想将第一个任务指派给"经理(managers)"组,而第二个用户任务指派给请假申请的提交人。因此需要为第一个任务添加candidateGroups属性。

<userTask id="approveTask" name="Approve or reject request" flowable:candidateGroups="managers"/>

用户任务assignee属性
第二个任务添加assignee属性。请注意我们没有像上面的’managers’一样使用静态值,而是使用一个流程变量动态指派。这个流程变量是在流程实例启动时传递的

<userTask id="holidayApprovedTask" name="Holiday approved" flowable:assignee="${employee}"/>

获得实际的任务列表,需要通过TaskService创建一个TaskQuery。我们配置这个查询只返回’managers’组的任务

TaskService taskService = processEngine.getTaskService();
List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("managers").list();
System.out.println("You have " + tasks.size() + " tasks:");
for (int i=0; i<tasks.size(); i++) {
  System.out.println((i+1) + ") " + tasks.get(i).getName());
}

可以使用任务Id获取特定流程实例的变量,并在屏幕上显示实际的申请

System.out.println("Which task would you like to complete?");
int taskIndex = Integer.valueOf(scanner.nextLine());
Task task = tasks.get(taskIndex - 1);
Map<String, Object> processVariables = taskService.getVariables(task.getId());
System.out.println(processVariables.get("employee") + " wants " +
    processVariables.get("nrOfHolidays") + " of holidays. Do you approve this?");

完成任务

七 实现JavaDelegate
最后一步也是要注意的一步,和前面的userTask不同,这个是serviceTask。

<serviceTask id="externalSystemCall" name="Enter holidays in external system"
    flowable:class="org.flowable.CallExternalSystemDelegate"/>

这时候要创建一个类CallExternalSystemDelegate,这个类继承org.flowable.engine.delegate.JavaDelegate,是用来处理execute,没有execute方法就没办法完成任务。

boolean approved = scanner.nextLine().toLowerCase().equals("y");
variables = new HashMap<String, Object>();
variables.put("approved", approved);
taskService.complete(task.getId(), variables);

这里要注意这个类的包名一定是org.flowable,一定是org.flowable,一定是org.flowable。

可以看一下我github的示例代码

完整代码

package com.flowable.holiday;

import org.flowable.engine.*;
import org.flowable.engine.impl.cfg.StandaloneProcessEngineConfiguration;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

/**
 * @Author: zhangpeng
 * @Description:
 * @Date: 2022/7/28
 */
public class HolidayRequest {

    public static void main(String[] args) {

        //(0)流程引擎的配置和实例初始化
        //ProcessEngineConfiguration 流程实例引擎的配置,配置数据库连接
        ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration()
                .setJdbcUrl("jdbc:h2:mem:flowable;DB_CLOSE_DELAY=-1")
                .setJdbcUsername("sa")
                .setJdbcPassword("")
                .setJdbcDriver("org.h2.Driver")
                .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);

        ProcessEngine processEngine = cfg.buildProcessEngine();

        //xml文件 deploy方法就是部署流程定义部署至Flowable引擎。从流程引擎processEngin获取流程存储库的的服务RepositoryService,往里面部署我们定义的流程
        RepositoryService repositoryService = processEngine.getRepositoryService();
        Deployment deployment = repositoryService.createDeployment()
                .addClasspathResource("holiday-request.bpmn20.xml")
                .deploy();

        //RepositoryService创建的ProcessDefinitionQuery对象实现
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .deploymentId(deployment.getId())
                .singleResult();
        System.out.println("Found process definition : " + processDefinition.getName());


//        (1)启动流程:输入申请的假期
        //屏幕输入字段作为
        Scanner scanner= new Scanner(System.in);

        System.out.println("Who are you?");
        String employee = scanner.nextLine();

        System.out.println("How many holidays do you want to request?");
        Integer nrOfHolidays = Integer.valueOf(scanner.nextLine());

        System.out.println("Why do you need them?");
        String description = scanner.nextLine();

        //RuntimeService开启实例
        RuntimeService runtimeService = processEngine.getRuntimeService();

        Map<String, Object> variables = new HashMap<String, Object>();
        variables.put("employee", employee);
        variables.put("nrOfHolidays", nrOfHolidays);
        variables.put("description", description);
        ProcessInstance processInstance =
                runtimeService.startProcessInstanceByKey("holidayRequest", variables);



        //(2)
        TaskService taskService = processEngine.getTaskService();
        List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("managers").list();
        System.out.println("You have " + tasks.size() + " tasks:");
        for (int i=0; i<tasks.size(); i++) {
            System.out.println((i+1) + ") " + tasks.get(i).getName());
        }
        System.out.println("Which task would you like to complete?");
        int taskIndex = Integer.valueOf(scanner.nextLine());
        Task task = tasks.get(taskIndex - 1);
        Map<String, Object> processVariables = taskService.getVariables(task.getId());
        System.out.println(processVariables.get("employee") + " wants " +
                processVariables.get("nrOfHolidays") + " of holidays. Do you approve this?");

        boolean approved = scanner.nextLine().toLowerCase().equals("y");
        variables = new HashMap<String, Object>();
        variables.put("approved", approved);
        taskService.complete(task.getId(), variables);


    }
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

flowable实战(四):构建命令行程序 的相关文章

  • “_加载小部件时出现问题”消息

    加载小部件时 如果找不到资源或其他内容 则会显示 加载小部件时出现问题 就这样 惊人的 此消息保留在主屏幕上 甚至没有说明加载时遇到问题的小部件 我通过反复试验弄清楚了这一点 但我想知道发生这种情况时是否有任何地方可以找到错误消息 Andr
  • 使用cameltestsupport进行Camel单元测试,模板始终为空

    我正在用 Camel 做一个简单的单元测试 我想做的就是从文件 在资源下 读取 JSON 内容 将其发送到 Java 类进行验证 这是我试图测试的路线 无论我做什么 模板 我用来发送正文 json 始终为空 这是我的代码 public cl
  • 如何使用 SimpleDateFormat 解析多种格式的日期

    我正在尝试解析文档中的一些日期 用户似乎以类似但不完全相同的格式输入了这些日期 以下是格式 9 09 9 2009 09 2009 9 1 2009 9 1 2009 尝试解析所有这些内容的最佳方法是什么 这些似乎是最常见的 但我想让我困扰
  • 使用 RecyclerView 适配器在运行时更改布局屏幕

    我有两个布局文件 如下所示 如果列表中存在数据 则我显示此布局 当列表为空时 我会显示此布局 现在我想在运行时更改布局 当用户从列表中删除最后一项时 我想将布局更改为第二张图片中显示的 空购物车布局 In getItemCount Recy
  • 在 HTTP 标头中发送 UTF-8 值会导致 Mojibake

    我想使用 servlet 发送阿拉伯语数据HTTPServletResponse给客户 我正在尝试这个 response setCharacterEncoding UTF 8 response setHeader Info arabicWo
  • Firestore - RecycleView - 图像持有者

    我不知道如何编写图像的支架 我已经设置了 2 个文本 但我不知道图像的支架应该是什么样子 你能帮我告诉我图像的文字应该是什么样子才能正确显示吗 holder artistImage setImageResource model getArt
  • 主线程如何在该线程之前运行?

    我有以下代码 public class Derived implements Runnable private int num public synchronized void setA int num try Thread sleep 1
  • Java 8 中函数式接口的使用

    这是来自的后续问题Java 8 中的 双冒号 运算符 https stackoverflow com questions 20001427 double colon operator in java 8其中 Java 允许您使用以下方式引用
  • 列表应该如何转换为具体的实现?

    假设我正在使用一个我不知道源代码的库 它有一个返回列表的方法 如下所示 public List
  • 无法加载或查找主类,可以在命令行中使用,但不能在 IDE 中使用[重复]

    这个问题在这里已经有答案了 在将其标记为重复之前 请先听我说完 我正在尝试使用 gradle 导入一个 java 项目 功能齐全 适用于所有其他笔记本电脑 没有问题 我的项目 100 正常运行 适用于所有其他笔记本电脑 当我的笔记本电脑被重
  • 如何将 Jfreechart(饼图)添加到 netbeans 的面板中

    我正在使用 netbeans gui 编辑器 并且正在尝试添加一个本身位于内部框架中的 Jfreechart 并且这个内部框架我想将其添加到面板中 正如您在此图中看到的那样 抱歉 我无法直接发布图像 因为我新手 http www flick
  • 获取给定类文件的目录路径

    我遇到的代码尝试从类本身的 class 文件所在的同一目录中读取一些配置文件 File configFiles new File this getClass getResource getPath listFiles new Filenam
  • Java 收集返回顶级项目的映射的嵌套流

    我有以下模型 class Item String name List
  • Spring Security OAuth2简单配置

    我有一个简单的项目 需要以下简单的配置 我有一个 密码 grant type 这意味着我可以提交用户名 密码 用户在登录表单中输入 并在成功时获得 access token 有了该 access token 我就可以请求 API 并获取用户
  • 如何配置 WebService 返回 ArrayList 而不是 Array?

    我有一个在 jax ws 上实现的 java Web 服务 此 Web 服务返回用户的通用列表 它运行得很好 Stateless name AdminToolSessionEJB RemoteBinding jndiBinding Admi
  • Espresso 和 Proguard 的 Java.lang.NoClassDefFoundError

    我对 Espresso 不太有经验 但我终于成功地运行了它 我有一个应用程序需要通过 Proguard 缩小才能处于 56K 方法之下 该应用程序以 3 秒的动画开始 因此我需要等到该动画结束才能继续 这就是我尝试用该方法做的事情waitF
  • 如何在 Eclipse Java 动态 Web 项目中使用 .properties 文件?

    我正在 Eclipse 中开发动态 Web 项目 我创建了一个 properties 文件来存储数据库详细信息 用户名 密码等 我通过右键单击项目和 New gt File 添加它 我使用了Java util包Properties类 但它不
  • Java的-XX:+UseMembar参数是什么

    我在各种地方 论坛等 看到这个参数 并且常见的答案是它有助于高并发服务器 尽管如此 我还是找不到 sun 的官方文档来解释它的作用 另外 它是Java 6中添加的还是Java 5中存在的 顺便说一句 许多热点虚拟机参数的好地方是这一页 ht
  • Hibernate 和可序列化实体

    有谁知道是否有一个框架能够从实体类中剥离 Hibernate 集合以使它们可序列化 我查看了 BeanLib 但它似乎只进行实体的深层复制 而不允许我为实体类中的集合类型指定实现映射 BeanLib 目前不适用于 Hibernate 3 5
  • Android 和 Java 中绘制椭圆的区别

    在Java中由于某种原因Ellipse2D Double使用参数 height width x y 当我创建一个RectF在Android中参数是 left top right bottom 所以我对适应差异有点困惑 如果在 Java 中创

随机推荐

  • OpenCV函数cvWaitKey(k)简介

    作者本人的开发环境为VS的MFC构架 结合OpenCV1 0进行图像的处理 可能很多像作者本人一样的初始开发程序员都会用到cvWaitKey 但是对cvWaitKey 的理解一知半解 在具体开发中会由此产生一些困惑 在查询了一些资料后 将资
  • Java实现文件分片上传

    为什么需要文件分片上传 大文件上传中断 假如我们有一个5G的文件 上传过程中突然中断我们该怎么办 上文件上传响应时间长 假如我们有个10G的文件 单次上传时间长 用户体验长 该怎么办 大文件上传重复上传 某些大文件 我们已经上传过了 我们不
  • JavaScript基础知识总结(6张思维导图)

    以下导图均为学习pink老师js基础视频时 自主整理的 有不足的地方 欢迎大家多多指出
  • 如何正确的进行网站入侵渗透测试

    大家都知道渗透测试就是为了证明网络防御按照预期计划正常运行而提供的一种机制 而且够独立地检查你的网络策略 一起来看看网站入侵渗透测试的正确知识吧 简单枚举一些渗透网站一些基本常见步骤 一 信息收集 要检测一个站首先应先收集信息如whois信
  • FastDB简单介绍及实例(Linux)

    本文内容主要是通过学习官网 博客及阅读官网demo做出的总结 FastDB是一个内存数据库 通过把数据加载到内存中实现对数据的操作 相比于传统的数据库 操作的速度更快 但是存在一个缺点就是使用FastDB数据库的应用程序都必须运行在同一台主
  • 【LWIP】stm32用CubeMX(6.4版)配置LwIP+Ping+TCPclient+TCPserver发送信息到PC(操作部分)

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 零 更新 2022 08 07 一 实验平台 二 手把手全程配置步骤 1 配置电脑环境 2 配置cubeMX 3 配置MDK Keil5 4 配置TCPcli
  • 监听屏幕滚动开始和结束事件(scroll start 和scroll stop)

    背景 最近在写一个专题页 产品要求右边导航栏在滑动的时候收起 滑动停止时显示 这样就需要监听到屏幕滚动 scroll start 事件和滚动结束 scroll end 事件 但是又不能为了这个功能专门引入jQuery mobile这个库 所
  • 来,看看这20个常用的宏定义!

    关注 星标公众号 直达精彩内容 ID 技术让梦想更伟大 作者 李肖遥 写好C语言 漂亮的宏定义很重要 使用宏定义可以防止出错 提高可移植性 可读性 方便性等等 下面列举一些成熟软件中常用的宏定义 1 防止一个头文件被重复包含 1 ifnde
  • npm 查看安装包版本

    npm info 安装包包名 如 npm info webpack
  • Linux查看CPU信息[//proc/loadavg]

    工作原理 基于 proc 文件系统 Linux 系统为管理员提供了非常好的方法 使其可以在系统运行时更改内核 而不需要重新引导内核系统 这是通过 proc 虚拟文件系统实现的 proc 文件虚拟系统是一种内核和内核模块用来向进程 proce
  • 1Panel 和宝塔有什么区别?

    宝塔是一款被广泛使用的 Linux 面板 与宝塔 Linux 面板相比 1Panel 的特色是开源和现代化 开源 1Panel 强调开源开放 广泛获取社区使用反馈 并快速迭代 现代化 一方面 1Panel 采纳最新的前端技术 并通过精心设计
  • SpringBoot Restful API 请求响应总结

    Controller 映射注解分为两大类 url映射注解和参数绑定注解 url映射注解 Controller 修饰class 用来创建处理http请求的对象 RestController Spring4之后加入的注解 原来在 Control
  • 2020-11-14

    MySQL学习周报 视图 数据库数据导入导出数据 数据库设计 1 视图 view 1 1 什么是视图 站在不同的角度去看到数据 同一张表的数据 通过不同的角度去看待 1 2 怎么创建视图 怎么删除视图 create view myview
  • 使用宝塔面板安装Rocket.Chat多功能团队聊天室

    安装 官方文档 https rocket chat docs 环境要求 NodeJS 8 11 4 Mongodb 4 0 9 Nginx 非必需 提示 由于官方建议的最低内存1G 所以512M或更小的建议加点虚拟内存 可以使用Swap一键
  • Linux 配置SSH免密登录

    介绍 SSH原理其实是非对称加密 即公钥加密私钥解密 免密登录原理 即事先将RSA非对称加密的公钥由主节点拷贝到到其他节点 只需实现主节点至其他节点的免密即可 流程如下 Client将自己的公钥存放在Server上 追加在文件authori
  • 华为荣耀8手机微信登录显示服务器错误,华为荣耀8手机无法登录360会员圈由于华为荣耀8手机无法登录3 爱问知识人...

    2017 10 12 05 41 48 保存个人资料恢复出厂值试一下 全部 2017 10 12 05 41 48 2017 10 12 05 41 48 会员的名称密码还有么 全部 2017 10 12 05 41 48 2017 10
  • STL算法之排序

    stl 算法库中提供的排序相关算法主要有以下几种 除了 q sort 定义在 cstdlib 头文件中 其余都定义在 algorithm 头文件 算法 功能 sort 排序 stable sort 稳定排序 保证等值情况时的原有顺序 par
  • 【C++】教大家在七夕new一个对象

    new是啥 new 是C 的关键字之一 它一般用来在堆上创建对象 但它与一般的创建对象的方法不同 它在创建对象时 会返回这个对象的指针 堆是啥 还有 和栈有什么区别 栈是由编译器自动分配和释放的 一般存放函数的参数值 局部变量的值等 速度较
  • c++primer 第十七章笔记 01tuple类型

    tuple类型 tuple看作一个 快速而随意 的数据结构 三个成员都设置为0 tuple
  • flowable实战(四):构建命令行程序

    实际上前面那些都是前置知识 真正上手的话其实还是一脸懵的情况 这里我也是按照文档生成一个最简单的demo 这个demo就是一个简单的Maven工程 你只要启动main方法就可以看到效果 github实例代码地址 这里如果直接下载代码 如果不