最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot整合flowable及其簡單的使用實例教程

 更新時間:2025年12月04日 09:28:54   作者:不會編程的猿丁  
Flowable是一個輕量級的Java開源業(yè)務(wù)流程引擎,支持BPMN2.0規(guī)范,提供流程定義、部署、任務(wù)管理、事件處理、表單管理、監(jiān)控和身份管理等功能,本文介紹了Flowable的核心組件、實現(xiàn)類、使用場景以及Spring Boot整合Flowable的步驟,包括配置和測試流程,感興趣的朋友一起看看吧

1. 什么是flowable?

Flowable是一個使用Java編寫的開源輕量級業(yè)務(wù)流程引擎,基于Apache 2.0協(xié)議,支持BPMN 2.0規(guī)范。它提供了從流程建模、執(zhí)行到監(jiān)控的全生命周期管理能力,能夠處理流程流轉(zhuǎn)相關(guān)的業(yè)務(wù),如審批流、工作流等。Flowable由Activiti項目發(fā)展而來,在保持原有功能的基礎(chǔ)上進(jìn)行了優(yōu)化和擴(kuò)展。

核心功能

  • 流程定義與部署:支持BPMN 2.0流程定義的部署,可創(chuàng)建流程實例,進(jìn)行查詢以及訪問運行中或歷史的流程實例與相關(guān)數(shù)據(jù)。
  • 任務(wù)管理:提供任務(wù)管理功能,允許用戶查詢、處理和完成任務(wù),任務(wù)可以是人工任務(wù)或系統(tǒng)任務(wù)。
  • 事件處理:支持事件處理機(jī)制,允許在流程執(zhí)行過程中觸發(fā)和監(jiān)聽各種事件,如開始事件、結(jié)束事件等。
  • 表單管理:可與表單設(shè)計器配合使用,在流程中定義動態(tài)表單,并掛載表單數(shù)據(jù)。
  • 實時監(jiān)控與報告:提供豐富的監(jiān)控功能,允許用戶實時查看流程實例的執(zhí)行狀態(tài)、任務(wù)執(zhí)行情況等。

核心組件

  • Flowable IDM:身份管理應(yīng)用,提供單點登錄認(rèn)證功能,管理用戶、組與權(quán)限。
  • Flowable Modeler:用于創(chuàng)建流程模型、表單、選擇表與應(yīng)用定義。
  • Flowable Task:運行時任務(wù)應(yīng)用,提供啟動流程實例、編輯任務(wù)表單等功能。
  • Flowable Admin:管理應(yīng)用,查詢BPMN、DMN等引擎,并提供修改流程實例等功能。
  • API服務(wù):通過ProcessEngine與Flowable交互,提供工作流/BPM方法。

使用場景

  • 審批流程:如請假申請、報銷審批等,可設(shè)計流程、部署定義、啟動實例、處理任務(wù)。
  • 工作流管理:適用于復(fù)雜多變的業(yè)務(wù)場景,根據(jù)業(yè)務(wù)流程建模,處理任務(wù)。
  • 企業(yè)數(shù)字化轉(zhuǎn)型:作為企業(yè)實現(xiàn)數(shù)字化轉(zhuǎn)型的重要工具,提高業(yè)務(wù)處理的效率和靈活性。

特點

  • 輕量級:以JAR形式發(fā)布,可輕易加入任何Java環(huán)境。
  • 高性能:專注于提供高性能的業(yè)務(wù)流程管理解決方案。
  • 靈活性:能夠靈活地嵌入到各種應(yīng)用和服務(wù)中。
  • 擴(kuò)展性:支持NoSQL、LDAP等,具有良好的擴(kuò)展性。

2. flowable的重要實現(xiàn)類

流程引擎相關(guān)

  • ProcessEngine:Flowable的核心組件,負(fù)責(zé)解析BPMN 2.0流程定義文件,并執(zhí)行其中的流程實例。它提供了豐富的API,方便開發(fā)者對流程實例進(jìn)行各種操作,如啟動、掛起、恢復(fù)、終止等。
  • ProcessEngineConfiguration:用于配置和初始化流程引擎,可以設(shè)置數(shù)據(jù)庫連接、事務(wù)管理器、監(jiān)聽器等信息。
  • RuntimeService:提供運行時流程實例和執(zhí)行的相關(guān)操作,如啟動流程實例、查詢運行時流程實例、獲取流程變量等。
  • TaskService:與任務(wù)相關(guān)的服務(wù)類,用于管理任務(wù)的創(chuàng)建、分配、完成等操作。
  • RepositoryService:用于管理流程定義和部署,可以部署流程定義文件、查詢流程定義、獲取流程模型等。

事務(wù)管理相關(guān)

  • CommandExecutorImpl:命令執(zhí)行器的實現(xiàn)類,負(fù)責(zé)執(zhí)行具體的命令。
  • SpringTransactionInterceptor:Spring事務(wù)攔截器,用于處理事務(wù)的傳播行為,確保流程操作在正確的事務(wù)上下文中執(zhí)行。
  • TransactionContextInterceptor:事務(wù)上下文攔截器,用于管理事務(wù)上下文中的命令執(zhí)行。

監(jiān)聽器相關(guān)

  • TaskListener:任務(wù)監(jiān)聽器接口,用于在任務(wù)的生命周期中監(jiān)聽特定事件,如任務(wù)創(chuàng)建、分配、完成等。
  • ExecutionListener:執(zhí)行監(jiān)聽器接口,用于在流程執(zhí)行的生命周期中監(jiān)聽特定事件。

流程圖生成相關(guān)

  • ProcessDiagramGenerator:流程圖生成器,用于根據(jù)BPMN模型生成流程圖。

身份管理相關(guān)

  • Flowable IDM:身份管理應(yīng)用,為所有Flowable UI應(yīng)用提供單點登錄認(rèn)證功能,并且為擁有IDM管理員權(quán)限的用戶提供了管理用戶、組與權(quán)限的功能。

建模與任務(wù)相關(guān)

  • Flowable Modeler:基于Web的建模工具,可用于創(chuàng)建分別符合BPMN 2.0、CMMN和DMN規(guī)范的業(yè)務(wù)流程。
  • Flowable Task:運行時任務(wù)應(yīng)用,提供了啟動流程實例、編輯任務(wù)表單、完成任務(wù),以及查詢流程實例與任務(wù)的功能。

管理與監(jiān)控相關(guān)

  • Flowable Admin:管理應(yīng)用,讓具有管理員權(quán)限的用戶可以查詢BPMN、DMN、Form及Content引擎,并提供了許多選項用于修改流程實例、任務(wù)、作業(yè)等。

3. SpringBoot整合flowable

maven導(dǎo)入flowable

maven中引入flowable-spring-boot-starter的相關(guān)依賴,我導(dǎo)入的是6.6.0版本,然后再導(dǎo)入數(shù)據(jù)庫相關(guān)依賴(flowable需要配合數(shù)據(jù)庫使用,且支持多種數(shù)據(jù)庫,我這里使用MySQL8.0為例)

        <dependency>
            <groupId>org.flowable</groupId>
            <artifactId>flowable-spring-boot-starter</artifactId>
            <version>6.6.0</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.33</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

制作流程圖

在idea中安裝bpmn流程圖的制作工具 Flowable BPMN visualizer

我這以IntelliJ IDEA 2024.3.1.1 (Ultimate Edition)為例

左上角四橫線圖片--File--Setting--Plugins--Installed,搜索 Flowable BPMN visualizer后點擊安裝

在resource目錄下新建processes文件夾(flowable默認(rèn)讀這個文件夾下的流程圖),新建文件xxx.bpmn20.xml(流程圖文件名必須以.bpmn20.xml或者bpmn結(jié)尾),右鍵文件選擇View BPMN

打開BPMN編輯頁面就可以制作自己想要的流程圖。

為了測試flowable我這里提供了一個簡單的流程圖

<?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:flowable="http://flowable.org/bpmn" 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" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.flowable.org/processdef">
  <!-- id為流程圖名稱要遵循xml的CNAME的起名規(guī)則  name為流程圖中文名稱 -->
  <process id="leave_flow" name="請假流程" isExecutable="true">
    <startEvent id="startEvent1"/>
    <!-- flowable:assignee="${userTask}"表示的意思是從哪個字段中獲取申請人的名稱   -->
    <userTask id="applyPerson" name="申請人" flowable:assignee="${userTask}">
      <extensionElements>
        <modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"><![CDATA[false]]></modeler:initiator-can-complete>
      </extensionElements>
    </userTask>
    <sequenceFlow id="sid-78321D10-B222-41F2-A655-2550B97688E0" sourceRef="startEvent1" targetRef="applyPerson"/>
    <userTask id="manager" name="經(jīng)理">
      <extensionElements>
        <!--  這是流程監(jiān)聽器所指定的審批人,class要指定監(jiān)聽      -->
        <flowable:taskListener event="create" class="com.sd.taskListener.ManagerTaskListener"/>
      </extensionElements>
    </userTask>
    <sequenceFlow id="sid-25A43AFD-67C2-41F7-87DF-25826AA220F8" sourceRef="applyPerson" targetRef="manager"/>
    <userTask id="boss" name="老板">
      <extensionElements>
        <!--  這是流程監(jiān)聽器所指定的審批人,class要指定監(jiān)聽      -->
        <flowable:taskListener event="create" class="com.sd.taskListener.BossTaskListener"/>
      </extensionElements>
    </userTask>
    <endEvent id="sid-27AE7469-EC65-4EF0-B85E-3A658BD85EE3"/>
    <!--  這里表示指定兩個流程監(jiān)聽器的處理動作,同意/駁回  -->
    <sequenceFlow id="refuse" name="駁回" sourceRef="manager" targetRef="applyPerson">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${result == "駁回"}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="pass" name="通過" sourceRef="manager" targetRef="boss">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${result == "同意"}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="refuse2" name="駁回" sourceRef="boss" targetRef="applyPerson">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${result == "駁回"}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="pass2" name="通過" sourceRef="boss" targetRef="sid-27AE7469-EC65-4EF0-B85E-3A658BD85EE3">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${result == "同意"}]]></conditionExpression>
    </sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_leave_flow">
    <bpmndi:BPMNPlane bpmnElement="leave_flow" id="BPMNPlane_leave_flow">
      <bpmndi:BPMNShape bpmnElement="startEvent1" id="BPMNShape_startEvent1">
        <omgdc:Bounds height="30.0" width="30.0" x="100.0" y="163.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="applyPerson" id="BPMNShape_applyPerson">
        <omgdc:Bounds height="80.0" width="100.0" x="175.0" y="138.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="manager" id="BPMNShape_manager">
        <omgdc:Bounds height="80.0" width="100.0" x="345.0" y="138.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="boss" id="BPMNShape_boss">
        <omgdc:Bounds height="80.0" width="100.0" x="510.0" y="138.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-27AE7469-EC65-4EF0-B85E-3A658BD85EE3" id="BPMNShape_sid-27AE7469-EC65-4EF0-B85E-3A658BD85EE3">
        <omgdc:Bounds height="28.0" width="28.0" x="735.0" y="164.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="refuse" id="BPMNEdge_refuse">
        <omgdi:waypoint x="395.0" y="217.95000000000002"/>
        <omgdi:waypoint x="395.0" y="291.0"/>
        <omgdi:waypoint x="225.0" y="291.0"/>
        <omgdi:waypoint x="225.0" y="217.95"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="pass" id="BPMNEdge_pass">
        <omgdi:waypoint x="444.9499999998897" y="178.0"/>
        <omgdi:waypoint x="509.99999999998465" y="178.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="pass2" id="BPMNEdge_pass2">
        <omgdi:waypoint x="609.9499999999675" y="178.0"/>
        <omgdi:waypoint x="735.0" y="178.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="refuse2" id="BPMNEdge_refuse2">
        <omgdi:waypoint x="560.0" y="138.0"/>
        <omgdi:waypoint x="560.0" y="76.0"/>
        <omgdi:waypoint x="225.0" y="76.0"/>
        <omgdi:waypoint x="225.0" y="138.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-78321D10-B222-41F2-A655-2550B97688E0" id="BPMNEdge_sid-78321D10-B222-41F2-A655-2550B97688E0">
        <omgdi:waypoint x="129.9499984899576" y="178.0"/>
        <omgdi:waypoint x="175.0" y="178.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-25A43AFD-67C2-41F7-87DF-25826AA220F8" id="BPMNEdge_sid-25A43AFD-67C2-41F7-87DF-25826AA220F8">
        <omgdi:waypoint x="274.95" y="178.0"/>
        <omgdi:waypoint x="344.99999999993565" y="178.0"/>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

查看流程圖

設(shè)置SpringBoot相關(guān)配置

spring:
  application:
    name: springboot-flowable
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/flowable_test?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8&nullCatalogMeansCurrent=true
    username: root
    password: 123456
server:
  port: 3333
flowable:
  #關(guān)閉定時任務(wù)job
  async-executor-activate: false
  #對數(shù)據(jù)庫表進(jìn)行操作,如果表不存在則會新建
  database-schema-update: true

配置flowable相關(guān)配置

防止流程圖中文亂碼配置

@Configuration
public class FlowableConfig implements EngineConfigurationConfigurer<SpringProcessEngineConfiguration> {
    @Override
    public void configure(SpringProcessEngineConfiguration springProcessEngineConfiguration) {
        springProcessEngineConfiguration.setActivityFontName("宋體");
        springProcessEngineConfiguration.setLabelFontName("宋體");
        springProcessEngineConfiguration.setAnnotationFontName("宋體");
    }
}

配置流程監(jiān)聽器

經(jīng)理監(jiān)聽器

public class ManagerTaskListener implements TaskListener {
    @Override
    public void notify(DelegateTask delegateTask) {
        delegateTask.setAssignee("經(jīng)理");
        System.out.println("經(jīng)理收到了流程");
    }
}

配置老板監(jiān)聽器

public class BossTaskListener implements TaskListener {
    @Override
    public void notify(DelegateTask delegateTask) {
        delegateTask.setAssignee("老板");
        System.out.println("老板收到了流程");
    }
}

編寫flowable相關(guān)操作

我這里演示發(fā)起流程,查看流程,獲取審批流程,審批同意,駁回以及查看流程圖

其他操作跟這些都大差不大,可自行擴(kuò)展

package com.sd.controller;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.engine.*;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.image.ProcessDiagramGenerator;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.*;
/**
 * @author sd
 * @create 2025-06-17-下午 4:06
 */
@RestController
@RequestMapping("/flowable")
public class FlowableController {
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private ProcessEngine processEngine;
    /**
     * 發(fā)起請假
     *
     * @param userId    用戶Id
     * @param days     請假天數(shù)
     * @param desc 描述
     */
    @GetMapping(value = "/add")
    public String addExpense(String userId,Integer days,String desc) {
        //設(shè)置流程參數(shù),用戶名等等
        HashMap<String, Object> map = new HashMap<>();
        map.put("userTask", userId);
        map.put("days", days);
        map.put("desc", desc);
        //啟動一個流程
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("leave_flow", map);
        //生成一個任務(wù)
        Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
        //第一步任務(wù)流程完成后,會按照流程圖自動分配給下一個流程
        taskService.complete(task.getId());
        return "提交成功\n流程Id為:" + processInstance.getId()
                + "\n任務(wù)id: " + task.getId()
                + "\n請假人為:" +userId
                + "\n請假天數(shù)為:" + days
                + "\n描述為:" + desc;
    }
    /**
     * 查詢請假流程
     *
     * @param userId 查詢?nèi)?
     *
     * */
    @GetMapping("findTask")
    public String findTask(String userId) {
        //從引擎中獲取任務(wù)
        TaskService taskService = processEngine.getTaskService();
        Task task = taskService.createTaskQuery().taskAssignee(userId).singleResult();
        return userId + "的任務(wù)ID:"+task.getId();
    }
    /**
     * 獲取審批管理列表
     *
     * @param userId 查詢?nèi)?
     *
     */
    @GetMapping(value = "/list")
    public Map<String,String> list(String userId) {
        Map<String,String> result = new HashMap<>();
        List<Task> tasks = taskService.createTaskQuery().taskAssignee(userId).orderByTaskCreateTime().desc().list();
        for (Task task : tasks) {
            result.put(task.getName(),task.getId());
        }
        return result;
    }
    /**
     * 批準(zhǔn)
     *
     * @param taskId 任務(wù)ID
     */
    @GetMapping(value = "apply")
    public String apply(String taskId) {
        //獲得任務(wù)
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (task == null) {
            throw new RuntimeException("流程不存在");
        }
        //通過審核
        HashMap<String, Object> map = new HashMap<>();
        map.put("result", "同意");
        taskService.complete(taskId, map);
        return  "任務(wù)ID:" + taskId + "---批準(zhǔn)!";
    }
    /**
     * 駁回
     */
    @GetMapping(value = "reject")
    public String reject(String taskId) {
        //獲得任務(wù)
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (task == null) {
            throw new RuntimeException("流程不存在");
        }
        HashMap<String, Object> map = new HashMap<>();
        map.put("result", "駁回");
        taskService.complete(taskId, map);
        return  "任務(wù)ID:" + taskId + "---駁回!";
    }
    /**
     * 生成流程圖
     *
     * @param taskId 任務(wù)ID
     */
    @GetMapping(value = "processDiagram")
    public void genProcessDiagram(HttpServletResponse httpServletResponse, String taskId) throws Exception {
        ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(taskId).singleResult();
        //流程走完的不顯示圖
        if (pi == null) {
            return;
        }
        Task task = taskService.createTaskQuery().processInstanceId(pi.getId()).singleResult();
        //使用流程實例ID,查詢正在執(zhí)行的執(zhí)行對象表,返回流程實例對象
        String InstanceId = task.getProcessInstanceId();
        List<Execution> executions = runtimeService
                .createExecutionQuery()
                .processInstanceId(InstanceId)
                .list();
        //得到正在執(zhí)行的flowable的Id
        List<String> flowableIds = new ArrayList<>();
        List<String> flows = new ArrayList<>();
        for (Execution exe : executions) {
            List<String> ids = runtimeService.getActiveActivityIds(exe.getId());
            flowableIds.addAll(ids);
        }
        //獲取流程圖
        BpmnModel bpmnModel = repositoryService.getBpmnModel(pi.getProcessDefinitionId());
        ProcessEngineConfiguration engconf = processEngine.getProcessEngineConfiguration();
        ProcessDiagramGenerator diagramGenerator = engconf.getProcessDiagramGenerator();
        InputStream in = diagramGenerator.generateDiagram(bpmnModel, "png", flowableIds, Collections.emptyList(), engconf.getActivityFontName(), engconf.getLabelFontName(), engconf.getAnnotationFontName(), null, 1.0, false);
        OutputStream out = null;
        byte[] buf = new byte[10240];
        int legth = 0;
        try {
            httpServletResponse.setContentType("image/png"); // 設(shè)置響應(yīng)類型為圖片
            out = httpServletResponse.getOutputStream();
            while ((legth = in.read(buf)) != -1) {
                out.write(buf, 0, legth);
            }
        } catch (IOException e) {
            System.out.println("生成流程圖失敗");
            throw new RuntimeException(e);
        } finally {
            if (in != null) {
                in.close();
            }
            if (out != null) {
                out.close();
            }
        }
    }
}

4. 測試flowable

如果在yml中配置了 database-schema-update: true 那么初次啟動項目會在控制臺打印的日志中看到很多建表語句,flowable會對不存在的表進(jìn)行創(chuàng)建

我沒有寫前端頁面就全部使用postman進(jìn)行測試,查看流程圖操作我會附著在發(fā)起,審批同意,駁回操作后面

發(fā)起流程

查詢對應(yīng)流程

這里只返回了查詢?nèi)撕腿蝿?wù)ID,其他操作可自行進(jìn)行擴(kuò)展

獲得審批列表

這里只返回了審批人以及流程ID

審批通過

審批通過后會執(zhí)行到流程圖設(shè)置的下一步

駁回

駁回后會返回到流程圖設(shè)置的上一步

先獲取老板的任務(wù)ID

注意:為什么在經(jīng)理審批時不用回去經(jīng)理的流程ID?因為經(jīng)理是提交申請后的第一步,提交申請我直接打印了任務(wù)ID,直接使用就行

進(jìn)行駁回

駁回后又返回到了第一步操作

到此這篇關(guān)于SpringBoot整合flowable及其簡單的使用實例教程的文章就介紹到這了,更多相關(guān)SpringBoot flowable使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Redisson分布式鎖的原理和代碼實例

    Redisson分布式鎖的原理和代碼實例

    這篇文章主要介紹了Redisson分布式鎖的原理和代碼實例,在分布式系統(tǒng)中,鎖機(jī)制是非常重要的,Redisson是一個基于Redis的Java應(yīng)用程序,常常被應(yīng)用作為分布式鎖的解決方案,需要的朋友可以參考下
    2024-01-01
  • spring boot項目快速構(gòu)建的全步驟

    spring boot項目快速構(gòu)建的全步驟

    這篇文章主要給大家介紹了關(guān)于spring boot項目快速構(gòu)建的全步驟,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用spring boot具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • Java后端向前端返回文件流實現(xiàn)下載功能

    Java后端向前端返回文件流實現(xiàn)下載功能

    后端可以使用Java中servlet提供的HttpServletResponse,核心步驟是要設(shè)置響應(yīng)的數(shù)據(jù)類型,設(shè)置為某一類文件類型或二進(jìn)制格式,以及響應(yīng)頭,然后用ServletOutputStream將文件以流的形式發(fā)送到前端,本文介紹Java后端向前端返回文件流實現(xiàn)下載功能,感興趣的朋友一起看看吧
    2023-12-12
  • java 中Executor, ExecutorService 和 Executors 間的不同

    java 中Executor, ExecutorService 和 Executors 間的不同

    這篇文章主要介紹了java 中Executor, ExecutorService 和 Executors 間的不同的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • 深入理解Java原生的序列化機(jī)制

    深入理解Java原生的序列化機(jī)制

    Java 提供了一種對象序列化的機(jī)制,該機(jī)制中,一個對象可以被表示為一個字節(jié)序列,該字節(jié)序列包括該對象的數(shù)據(jù)、有關(guān)對象的類型的信息和存儲在對象中數(shù)據(jù)的類型。下面小編和大家來一起學(xué)習(xí)一下吧
    2019-06-06
  • SpringBoot項目啟動時提示程序包不存在和找不到符號的處理方法

    SpringBoot項目啟動時提示程序包不存在和找不到符號的處理方法

    最近接手同事開發(fā)的一個Springboot工作項目,從svn上整體拉取下來后,構(gòu)建完成后,啟動的時候遇到了程序包找不到的情況,所以本文記錄了SpringBoot項目啟動時提示程序包不存在和找不到符號的處理方法,需要的朋友可以參考下
    2024-05-05
  • springMVC的生命周期詳解

    springMVC的生命周期詳解

    本篇文章主要介紹了springMVC的生命周期詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-03-03
  • SpringBoot中MVC的自動配置詳解

    SpringBoot中MVC的自動配置詳解

    這篇文章主要介紹了SpringBoot中MVC的自動配置詳解,在實際開發(fā)過程中,還有一些老的系統(tǒng)在使用xml格式來傳輸數(shù)據(jù),SpringBoot也提供了xml格式數(shù)據(jù)的返回,只需要小小的改動,就可以實現(xiàn),需要的朋友可以參考下
    2023-09-09
  • Java設(shè)計模式之策略模式解析

    Java設(shè)計模式之策略模式解析

    這篇文章主要介紹了Java設(shè)計模式之策略模式解析,在策略模式中,一個類的行為或其算法可以在運行時更改,這種類型的設(shè)計模式屬于行為型模式,需要的朋友可以參考下
    2023-10-10
  • Java原子操作CAS原理解析

    Java原子操作CAS原理解析

    這篇文章主要介紹了Java原子操作CAS原理解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-10-10

最新評論

泸溪县| 溧水县| 苍梧县| 思南县| 呼伦贝尔市| 吉安县| 来凤县| 岳阳县| 康平县| 莆田市| 房产| 罗江县| 合山市| 佛教| 泽普县| 孟津县| 迁安市| 清镇市| 积石山| 乌海市| 平乐县| 裕民县| 南陵县| 六安市| 方正县| 西乌珠穆沁旗| 大新县| 印江| 赤峰市| 黑水县| 建始县| 安丘市| 抚松县| 建始县| 绥芬河市| 江源县| 余干县| 胶州市| 茌平县| 东至县| 江门市|