SpringBoot: введение и практика работы с механизмом процессов Camunda
SpringBoot: введение и практика работы с механизмом процессов Camunda

1. Основные компоненты

  • Process Engine-процессный двигатель
  • Web Applicatons- веб-страница управления
1.Введение API

Официальная документация

https://docs.camunda.org/manual/7.18/user-guide/process-engine/process-engine-api/

Ниже приведены некоторые документы с официального сайта. Если у вас есть время, вы можете посмотреть. Вот некоторые основные вещи.

2. ProcessEngine

Это механизм процессов, с помощью которого вы можете получать сопутствующие услуги. Он объединяет множество сопутствующих услуг. Реализация по умолчанию следующая.

**RepositoryService **Эта служба обеспечивает операции по управлению и эксплуатации развертываний и определений процессов, что является первым приоритетом при использовании camunda.

**RuntimeService **Связано с запуском, запуском экземпляров процесса, удалением, поиском и т. д.

**TaskService **Все операции, связанные с задачами, такие как завершение, распространение, утверждение и т. д.

HistoryService Предоставлять услуги исторических данных, собранных двигателями

IdentityService Связан с пользователем, редко используется на практике

3. Интеграция Springboot

Зависит от интеграции maven

  • https://mvnrepository.com/search?q=org.camunda.bpm.springboot

При необходимости вы можете указать версию, я использую здесь 7.18. Требуются три зависимости maven, которые соответствуют механизму процессов, платформе веб-управления и пакету интерфейса операции rest API.

Язык кода:javascript
копировать
<dependency>
    <groupId>org.camunda.bpm.springboot</groupId>
    <artifactId>camunda-bpm-spring-boot-starter</artifactId>
    <version>7.18.0</version>
</dependency>
<dependency>
    <groupId>org.camunda.bpm.springboot</groupId>
    <artifactId>camunda-bpm-spring-boot-starter-rest</artifactId>
    <version>7.18.0</version>
</dependency>
<dependency>
    <groupId>org.camunda.bpm.springboot</groupId>
    <artifactId>camunda-bpm-spring-boot-starter-webapp</artifactId>
    <version>7.18.0</version>
</dependency>

база данных Я использую здесь MySQL и создал новую базу данных. camunda (настраиваемый), необходимая структура таблицы будет автоматически сгенерирована после запуска

POM-файл

Язык кода:javascript
копировать
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>camunda-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>camunda-demo</name>
    <description>camunda-demo</description>
 
    <properties>
        <java.version>17</java.version>
    </properties>
 
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.camunda.bpm.springboot</groupId>
            <artifactId>camunda-bpm-spring-boot-starter</artifactId>
            <version>7.18.0</version>
        </dependency>
        <dependency>
            <groupId>org.camunda.bpm.springboot</groupId>
            <artifactId>camunda-bpm-spring-boot-starter-rest</artifactId>
            <version>7.18.0</version>
        </dependency>
        <dependency>
            <groupId>org.camunda.bpm.springboot</groupId>
            <artifactId>camunda-bpm-spring-boot-starter-webapp</artifactId>
            <version>7.18.0</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.32</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
 
 
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
 
</project>

application.yml

Язык кода:javascript
копировать
server:
  port: 8081
 
 
# информация для входа в камунду Конфигурация
camunda.bpm:
  admin-user:
    id: admin  #имя пользователя
    password: 123456  #пароль
    firstName: yu
  filter:
    create: All tasks
 
# информация о соединении MySQL
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:8101/camunda
    username: root
    password: 123456
    type: com.mysql.cj.jdbc.MysqlDataSource
4. Эффект запуска

Подготовьте подготовительные работы, а эффект после запуска следующий:

база данныхструктура таблицы

Структура таблицы, автоматически создаваемая после запуска, выглядит следующим образом.

Вероятно, существует несколько модулей таблиц. Наиболее важные из них представлены подробно:

  • ACT_ID_

Эта часть представляет пользовательский модуль. Информация о пользователе в файле конфигурации находится в этом модуле.

  • ACT_HI_

Представляет историю процесса

  • act_hi_actinst: История выполненных работ
  • act_hi_taskinst:История выполнения задач
  • act_hi_procinst:История экземпляров процесса выполнения
  • act_hi_varinst:процесспеременнаятаблица истории
  • ACT_RE_

Представляет хранилище ресурсов процесса

  • act_re_procdef:процесс Определить хранилище
  • act_re_deployment: Автоматическое развертывание, Springboot будет повторно развертываться при каждом запуске и генерировать записи.
  • ACT_RU_

Представляет данные таблицы во время выполнения процесса и будут удалены после завершения процесса.

  • act_ru_execution:время выполненияпроцесс Пример
  • act_ru_task:Задачи времени выполнения
  • act_ru_variable:время выполнения的процесспеременная
  • ACT_GE_

Обработка общих данных

  • act_ge_bytearray:Файлы для каждого развертывания2шестнадцатеричные данные,Итак, после изменения файла if,Перезагрузка бесполезна,Потому что запись была восстановлена,Нужно очистить базу данные или эта запись таблицы

Интерфейс входа в систему

Адрес для входа http://localhost:8081/,Введите имя пользователя и пароль admin,123456 в файле конфигурации.

главная консоль

После успешного входа в систему, как показано ниже, ниже описывается конкретное использование.

два、Специализированная бизнес-интеграция

1. Нарисуйте блок-схему

скачать Сначала вам нужен инструмент Camunda Modeler Приходите и рисуйте, скачать адрес:

  • https://camunda.com/download/modeler/

После распаковки откройте его следующим образом:

рисовать

Создать новый

Я немного нарисовал здесь. Не буду вдаваться в подробности, как это нарисовать. Конечный эффект следующий: имитация процесса ОА.

Классификация задач

Представлены только два наиболее часто используемых из них.

  • Пользовательская задача

Конкретно это задача, которую нужно выполнить вручную, то есть после того, как мы написали бизнес-код, нам нужно вызвать код

Язык кода:javascript
копировать
taskService.complete(taskId, variables);

задачи, которые будут выполнены

  • Сервисная задача

Система автоматически поможет нам выполнить задания

шлюз

Разделенные на несколько категорий, они будут обрабатываться в соответствии с передаваемыми нами переменными процесса и заданными нами условиями.

  • эксклюзивныйшлюз(exclusive gateway)

Этот шлюз будет идти только в одну сторону,Когда мы подошли к этому шлюзу,Он найдет первую задачу, отвечающую условиям, сверху вниз и спустится вниз.

  • параллельныйшлюз(Parallel Gateway)

Этот шлюз не требует установки условий и выполнит все задачи.

  • Инклюзивный шлюз

Этот шлюз возьмет на себя одну или несколько задач, соответствующих условиям

Пример

Как показано выше содержит шлюз, в шлюзе задается условие выражения, а параметры задаются из переменных процесса

Два параметра:

Язык кода:javascript
копировать
switch2d 、 switch3d
  • Если оба варианта верны, то переходим к задачам 1 и 3.
  • Если значение switch2d равно true, а значение switch3d — false, будет выполнена только задача 1.
  • Если значение switch3d равно true, а значение switch2d — false, будет выполнена только задача 3.
  • есливсе дляfalse,Затем перейдите непосредственно к шлюзу,тогда конец
2.Представить проекты

Сохраните нарисованный файл блок-схемы как test_1.bpmn, resourcesСоздать в проекте Springboot прямо сейчас новая папка bpmn,вставить,

Перезапустите проект и обнаружите, что веб-интерфейс интегрирован.

3. Специальное развитие

Напишите несколько тестовых контроллеров и сервисов.

controller

service

Язык кода:javascript
копировать
public void startProcess() {
    ProcessInstance instance = runtimeService.startProcessInstanceByKey("key");
    System.out.println(instance.toString());
}

public List<ProcessDefinition> findProcesses() {
    return repositoryService.createProcessDefinitionQuery().list();
}

public List<Task> findTasks() {
    return taskService.createTaskQuery().list();
}

Процесс запуска прошел успешно, что указывает на то, что проблема не является серьезной. Далее будут внесены детальные улучшения бизнеса.

В следующей статье представлена ​​подробная бизнес-интеграция и использование различных API (передача переменных, автоматические задачи).

Использование API

API, связанный с процессом

Процесс создания:

Первая задача будет создана одновременно

Язык кода:javascript
копировать
ProcessInstance instance = runtimeService.startProcessInstanceByKey(processKey, params);

приостановить процесс

После приостановки процесса будет сообщено об ошибке, если соответствующие задачи будут выполнены снова, и сначала задачу необходимо повторно активировать.

Язык кода:javascript
копировать
runtimeService.suspendProcessInstanceById(instance.getId());

Процесс реактивации

Язык кода:javascript
копировать
runtimeService.activateProcessInstanceById(instance.getId());

удалить процесс

Задачи также будут удалены.

Язык кода:javascript
копировать
runtimeService.deleteProcessInstance(instance.getId(), «Удалить вручную»);

Все вышеперечисленное можно найти в таблице истории процессов. act_hi_procinst Запрос здесь

API, связанный с задачами

Для классов запросов на основе служб вы можете сначала создать запрос, а затем прикрепить условия запроса и несколько примеров.

Язык кода:javascript
копировать
List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().list();
List<Task> list = taskService.createTaskQuery().taskAssignee("zhangsan").list();
List<ProcessInstance> instances = runtimeService.createProcessInstanceQuery().listPage(1, 10);

Запрос исторических задач

Язык кода:javascript
копировать
List<HistoricProcessInstance> list = historyService.createHistoricProcessInstanceQuery().list();

Запросить текущую задачу/нумерацию страниц

Язык кода:javascript
копировать
List<Task> list = taskService.createTaskQuery().orderByTaskCreateTime().desc().list();

Откат задачи

Общая идея состоит в том, чтобы получить текущую задачу и предыдущую историческую задачу текущей задачи, а затем перезапустить

Пример кода

Язык кода:javascript
копировать
 Task activeTask = taskService.createTaskQuery()
                .taskId(taskId)
                .active()
                .singleResult();
        List<HistoricTaskInstance> historicTaskInstance = historyService.createHistoricTaskInstanceQuery()
                .processInstanceId(instanceId)
                .orderByHistoricActivityInstanceStartTime()
                .desc()
                .list();
 
        List<HistoricTaskInstance> historicTaskInstances = historicTaskInstance.stream().filter(v -> !v.getTaskDefinitionKey().equals(activeTask.getTaskDefinitionKey())).toList();
 
        Assert.notEmpty(historicTaskInstances, «Это уже начальная задача!»);
        HistoricTaskInstance curr = historicTaskInstances.get(0);
 
        runtimeService.createProcessInstanceModification(instanceId)
                .cancelAllForActivity(activeTask.getTaskDefinitionKey())
                .setAnnotation("Повторное выполнение")
                .startBeforeActivity(curr.getTaskDefinitionKey())
                .execute();
4. Переменные процесса

Включает переменную информацию, генерируемую в ходе процесса.,В том числе и переменная, контролирующая течение процессов,шлюз, переменная и т. д., необходимые для процесса заполнения бизнес-формы. Используется во многих местах

Передача переменной процесса

Переменные в конечном итоге будут существовать act_ru_variable внутри этой таблицы

существоватьрисоватьпроцесскогда рисуешь,еслида Пользовательские задачи(userService) Вы можете установить переменные, такие как исполнитель,

Есть несколько способов написать

  • Пиши до смерти, как Чжансан.
  • выражение, такое как написанное выше ${user},Для этого необходимо передать параметры,Фактически, он передается при запуске параметров.,Передать параметры,Необязательное значение — одноMap<String, Object>,Вы можете проверить вторичные параметры в последующем процессе.,То, что написано выше, это пользователь, Следовательно, ключ в карте должен содержать пользователя, иначе будет сообщено об ошибке.

О расширении переменная,Это можно установить в блок-схеме рисунка.,Способ доставки остался прежним.,В блок-схеме это написано ниже:

Код:

Язык кода:javascript
копировать
ProcessInstance instance = runtimeService.startProcessInstanceByKey(key, new HashMap<>());

Переменные настройки

Язык кода:javascript
копировать
runtimeService.setVariable(instance.getId(), Constants.PATIENT_ID, relatedId);

Переменный запрос

Язык кода:javascript
копировать
 Object variable = runtimeService.getVariable(instance.getId(), Constants.GENERAL_ID);

история Переменный запрос

Язык кода:javascript
копировать
Переменная HistoricVariableInstanceInstance = HistoryService.createHistoricVariableInstanceQuery().processInstanceId(bo.getId().toString()).
            Имя переменной(Константы.PATIENT_ID).singleResult();
//переменнаяценить
переменнаяInstance.getValue();
//переменная имя
переменнаяInstance.getName();

Есть два основных типа задач для бэкэнда.

UserTask-userTask

То есть задачи, требующие участия пользователя, поскольку процесс выполнения рабочего процесса должен включать в себя такие задачи, как утверждение и проверка, требующие участия пользователя. В это время пользователям необходимо участвовать, а затем вызывать интерфейс для выполнения задачи.

Задача службы-serviceTask

То есть задачи, которые выполняются автоматически, например задачи, которые система автоматически сохраняет, изменяет статус и т. д. после отправки пользователем.

Type

Тип задачи является ключевым. Вы можете вызывать методы Java, методы Spring Bean и т. д. в соответствии с соответствующей конфигурацией. Существует несколько типов.

Рекомендуется использовать – Делегированное выражение!!!

В системных задачах, поскольку они выполняются автоматически, различную бизнес-логику необходимо внедрять в реальные приложения. В конструкции блок-схемы вы можете вызвать Java-код для выполнения следующим образом и настроить bean-компонент с тем же именем весной.

Выражения конфигурации можно использовать для настройки интерфейса JavaDelegate с использованием имен классов. Следующий метод более рекомендуется. Этот тип позволяет гибко настраивать bean-компоненты и Spring для внедрения бизнес-методов, таких как службы.

Язык кода:javascript
копировать
@Bean("t17")
JavaDelegate t17() {
    return execution -> {
        Map<String, Object> variables = execution.getVariables();
        Task task = taskService.createTaskQuery().processInstanceId(execution.getProcessInstanceId()).singleResult();
        //Бизнес-логика
        task.setOwner(String.valueOf(dentistId));
    };
}

Java Class :

Чтобы настроить имя класса Java, вам необходимо реализовать интерфейс JavaDelegate. Обратите внимание, что это полное имя. Вы не можете использовать конфигурацию bean-компонента Spring! ! !

Язык кода:javascript
копировать
@Component
public class T17Delegate implements JavaDelegate {
 
    @Override
    public void execute(DelegateExecution execution) throws Exception {
            String taskId = execution.getId();
            String instanceId = execution.getProcessInstanceId();
            Map<String, Object> variables = execution.getVariables();
    }
}

Следующие две конфигурации могут использоваться с пружиной

Expression:

Выражение EL, вызывающий метод класса Java, спецификация:

Язык кода:javascript
копировать
expression=“#{monitorExecution.execution(execution)}”
@Component("monitorExecution")
public class MonitorExecution {
    public void execution(DelegateExecution execution){
        String processInstanceId = execution.getProcessInstanceId();
    }
}
5. Прослушиватель задач - Прослушиватель задач

Прослушиватели задач используются для выполнения пользовательской логики или выражений Java при возникновении определенного события, связанного с задачей. Его можно добавить только в определение процесса как дочерний элемент пользовательской задачи.

Обратите внимание, что это также должно происходить как дочерний элемент расширения BPMN 2.0 и внутри пространства имен Camunda, поскольку прослушиватели задач созданы специально для механизма Camunda.

Применимые сценарии:

Язык кода:javascript
копировать
@Bean
TaskListener t21() {
    return delegateTask -> {

        String taskId = delegateTask.getId();
        String instanceId = delegateTask.getProcessInstanceId();
        
        Map<String, Object> variables = delegateTask.getVariables();
        // TODO: 20log/3/22
        delegateTask.setVariable("", "");
    };
}
6. Прослушиватель выполнения — Прослушиватель выполнения

Прослушиватели выполнения выполняют внешний код Java или оценивают выражения, когда во время выполнения процесса происходят определенные события. Его можно использовать в любой задаче. События, которые можно зафиксировать:

  • Начало и конец экземпляра процесса.
  • Сделайте переход.
  • Начало и конец деятельности.
  • Начало и конец шлюза.
  • Начало и конец промежуточных событий.
  • конечное стартовое событие или начало конечного события

Применяемые сценарии: установка хода выполнения задачи в конце каждой задачи.

Язык кода:javascript
копировать
 public class ExampleExecutionListenerOne implements ExecutionListener {
 
    public void notify(DelegateExecution execution) throws Exception {
      execution.setVariable("variableSetInExecutionListener", "firstValue");
      execution.setVariable("eventReceived", execution.getEventName());
    }
  }
7.Свойства расширения-Свойства расширения.

Расширенные атрибуты подходят для многих настраиваемых бизнес-атрибутов, таких как настройка хода бизнес-процесса.

8. Разрешения на обработку и настройки создателя

IdentityService — это служба, связанная с аутентификацией, но в нашей фактической разработке мы обычно используем нашу собственную систему аутентификации, поэтому ее можно настроить с помощью API, предоставленного camunda. Подробности см. в классе IdentityServiceImpl, который также использует ThreadLocal для сохранения аутентификации. Информация, код ниже.

Язык кода:javascript
копировать
private ThreadLocal<Authentication> currentAuthentication = new ThreadLocal<Authentication>();

Настройки информации о пользователе:

Язык кода:javascript
копировать
// Userutil — это наш собственный инкапсулированный класс пользовательских инструментов.
identityService.setAuthenticatedUserId(UserUtil.getUserId().toString());
 
//Получать
Authentication authentication = identityService.getCurrentAuthentication();

Он имеет множество встроенных функций, например, при запуске процесса,По умолчанию будет найден человек, вошедший в систему.,Этот классDefaultHistoryEventProducer

Язык кода:javascript
копировать
// set super process instance id
  ExecutionEntity superExecution = executionEntity.getSuperExecution();
  if (superExecution != null) {
    evt.setSuperProcessInstanceId(superExecution.getProcessInstanceId());
  }

  //state
  evt.setState(HistoricProcessInstance.STATE_ACTIVE);

  // set start user Id
  evt.setStartUserId(Context.getCommandContext().getAuthenticatedUserId());
9. Настройки исполнителя и инициатора задач
Язык кода:javascript
копировать
//Установим исполнителя по идентификатору задачи
TaskService.setAssignee(task.getId(), UserUtil.getUserId().toString());
boy illustration
RasaGpt — платформа чат-ботов на основе Rasa и LLM.
boy illustration
Nomic Embed: воспроизводимая модель внедрения SOTA с открытым исходным кодом.
boy illustration
Улучшение YOLOv8: EMA основана на эффективном многомасштабном внимании, основанном на межпространственном обучении, и эффект лучше, чем у ECA, CBAM и CA. Малые цели имеют очевидные преимущества | ICASSP2023
boy illustration
Урок 1 серии Libtorch: Тензорная библиотека Silky C++
boy illustration
Руководство по локальному развертыванию Stable Diffusion: подробные шаги и анализ распространенных проблем
boy illustration
Полностью автоматический инструмент для работы с видео в один клик: VideoLingo
boy illustration
Улучшения оптимизации RT-DETR: облегченные улучшения магистрали | Support Paddle облегченный rtdetr-r18, rtdetr-r34, rtdetr-r50, rtdet
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | Деформируемое внимание с большим ядром (D-LKA Attention), большое ядро ​​​​свертки улучшает механизм внимания восприимчивых полей с различными функциями
boy illustration
Создано Datawhale: выпущено «Руководство по тонкой настройке развертывания большой модели GLM-4»!
boy illustration
7B превышает десятки миллиардов, aiXcoder-7B с открытым исходным кодом Пекинского университета — это самая мощная модель большого кода, лучший выбор для корпоративного развертывания.
boy illustration
Используйте модель Huggingface, чтобы заменить интерфейс внедрения OpenAI в китайской среде.
boy illustration
Оригинальные улучшения YOLOv8: несколько новых улучшений | Сохранение исходной информации — алгоритм отделяемой по глубине свертки (MDSConv) |
boy illustration
Второй пилот облачной разработки | Быстро поиграйте со средствами разработки на базе искусственного интеллекта
boy illustration
Бесшовная интеграция, мгновенный интеллект [1]: платформа больших моделей Dify-LLM, интеграция с нулевым кодированием и встраивание в сторонние системы, более 42 тысяч звезд, чтобы стать свидетелями эксклюзивных интеллектуальных решений.
boy illustration
Решенная Ошибка | Загрузка PyTorch медленная: TimeoutError: [Errno 110] При загрузке факела истекло время ожидания — Cat Head Tiger
boy illustration
Brother OCR, библиотека с открытым исходным кодом для Python, которая распознает коды проверки.
boy illustration
Новейшее подробное руководство по загрузке и использованию последней демонстрационной версии набора данных COCO.
boy illustration
Выпущен отчет о крупной модели финансовой отрасли за 2023 год | Полный текст включен в загрузку |
boy illustration
Обычные компьютеры также могут работать с большими моделями, и вы можете получить личного помощника с искусственным интеллектом за три шага | Руководство для начинающих по локальному развертыванию LLaMA-3
boy illustration
Одной статьи достаточно для анализа фактора транскрипции SCENIC на Python (4)
boy illustration
Бросая вызов ограничениям производительности небольших видеокарт, он научит вас запускать большие модели глубокого обучения с ограниченными ресурсами, а также предоставит полное руководство по оценке и эффективному использованию памяти графического процессора!
boy illustration
Команда Fudan NLP опубликовала 80-страничный обзор крупномасштабных модельных агентов, в котором в одной статье представлен обзор текущего состояния и будущего агентов ИИ.
boy illustration
[Эксклюзив] Вы должны знать о новой функции JetBrains 2024.1 «Полнострочное завершение кода», чтобы решить вашу путаницу!
boy illustration
Краткое изложение базовых знаний о регистрации изображений 1.0
boy illustration
Новейшее подробное руководство по установке и использованию библиотеки cv2 (OpenCV, opencv-python) в Python.
boy illustration
Легко создайте локальную базу знаний для крупных моделей на основе Ollama+AnythingLLM.
boy illustration
[Решено] ошибка установки conda. Среда решения: не удалось выполнить первоначальное зависание решения. Повторная попытка с помощью файла (графическое руководство).
boy illustration
Одна статья поможет вам понять RAG (Retrival Enhanced Generation) | Введение в концепцию и теорию + практику работы с кодом (включая исходный код).
boy illustration
Эволюция архитектуры шлюза облачной разработки
boy illustration
Docker и Kubernetes [Разработка контейнерных приложений с помощью Python]