Activiti工作流

Activity面试题库 Activity1.什么是Activity2.setContentView()3.生命周期 1.什么是Activity Activity是Android的四大组件之一,Activity是用户操作的可视化界面;为用户提供了可以完成操作指令串口。创建完Activity之后,需要调用setContentView()方法来完成界面的显示。 2.setContentView() 在Activity中可以多次... 阅读详情

分享一下手把手教你如何玩转Activiti工作流

还未完善

场景:学校    

主角:阿毛  ,   班主任   ,教务处处长

问题:有一天,阿毛到学校,感觉到身体不舒服,然后想跟班主任请假,然后班主任告诉阿毛说,你想请假,那么就必须要请假条,这个上面必须要我同意,然后再拿到教务处去盖章,然后交给我,这样才可以进行请假。。阿毛,想着,怎么请个假都这么麻烦,这么多层次处理问题,能不能简便一点。。。。好烦好烦~!!~~

分析:从上面的小例子,我们可以很明显的得到一个结论,就是:

请假流程:阿毛------》提交申请-----》班主任审批-----》教务处审批-----》请假成功

也就是说,这种问题就是一种流式的控制管理,当然,这是最简单的,因为里面没有包含着回馈,相当于只是一个方向。其实,到这里,Activiti的定义就已经出来了。。。。。
 

大纲:

之前做过一些项目没有用到工作流,都是以状态控制整个流程,现在系统化的将工作流分享一下

使用activiti-designer-5.18.0.zip

2.创建SpringBoot工程

①编辑POM文件

<!-- 继承SpringBoot官方指定的父工程 -->
<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>1.5.12.RELEASE</version>
</parent>
<dependencies>
	<!-- MySQL驱动 -->
	<dependency>
		<groupId>mysql</groupId>
		<artifactId>mysql-connector-java</artifactId>
	</dependency>
	<!-- 数据库连接池 -->
	<dependency>
		<groupId>com.alibaba</groupId>
		<artifactId>druid</artifactId>
		<version>1.0.5</version>
	</dependency>
	<!-- MyBatis场景启动器 -->
	<dependency>
		<groupId>org.mybatis.spring.boot</groupId>
		<artifactId>mybatis-spring-boot-starter</artifactId>
		<version>1.1.1</version>
	</dependency>
	<!-- Activiti场景启动器 -->
	<dependency>
		<groupId>org.activiti</groupId>
		<artifactId>activiti-spring-boot-starter-basic</artifactId>
		<version>5.21.0</version>
	</dependency>
	<!-- 基本场景启动器 -->
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter</artifactId>
	</dependency>
	<!-- SpringBoot测试支持 -->
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-test</artifactId>
	</dependency>
</dependencies>

特别说明:请把mybatis-spring-boot-starter的依赖放在activiti-spring-boot-starter-basic的前面以避免jar包冲突问题。jar包冲突的表现是:java.lang.ClassNotFoundException: org.apache.ibatis.annotations.Mapper。

依赖顺序和依赖传递的关系: mybatis-spring-boot-starter依赖mybatis-3.4.0.jar,而activiti-spring-boot-starter-basic依赖mybatis-3.3.0.jar,对于这种情况,Maven以顺序靠前的为准。现在如果导入的是mybatis-3.3.0.jar就会抛出异常,而mybatis-3.4.0.jar是正确的,所以要让mybatis-spring-boot-starter的依赖放在activiti-spring-boot-starter-basic的前面。

②主启动类

@SpringBootApplication
public class MainApplication {
	
	public static void main(String[] args) {
		SpringApplication.run(MainApplication.class, args);
	}

}

③测试类

@RunWith(SpringRunner.class)
@SpringBootTest
public class ProcessTest {
	
	@Autowired
	private ProcessEngine processEngine;
	
	@Test
	public void createTable() {
		System.out.println(processEngine);
	}

}

④yml配置

spring:
  datasource:
    name: mydb
    type: com.alibaba.druid.pool.DruidDataSource
    url: jdbc:mysql://127.0.0.1:3306/db_activiti
    username: root
    password: root
    driver-class-name: com.mysql.jdbc.Driver

⑤特别操作

在src/main/java目录下创建processes目录,否则将抛出异常:java.io.FileNotFoundException: class path resource [processes/] cannot be resolved to URL because it does not exist。processes目录的作用是存放bpmn流程定义文件,并对bpmn文件进行自动部署。如果创建到src/main/resources目录下则要求processes目录下至少存在一个文件(任意)。

三、流程操作

1.创建第一个流程图

2.流程部署

①Java代码

注意:如果放在processes目录下会被自动部署,下面的Java代码是手动部署。

@RunWith(SpringRunner.class)
@SpringBootTest
public class ProcessTest {
    @Autowired
    private RepositoryService repositoryService;
    @Test
    public void test01ProcessDefinitionDeployment() {
        //部署:将流程定义文件中流程定义信息存入数据库
        repositoryService
            .createDeployment()     //创建部署构建器对象
            .addClasspathResource("MyProcess.bpmn")   //添加要部署的流程定义文件名
            .deploy();      //执行部署
    }

}

②数据库表分析

[1]act_ge_bytearray表

二进制数据表,存储了流程定义图形的XML文件和图片信息
保存流程定义的xml信息
保存流程定义的图片

[2]act_re_deployment表

部署信息表,存储了部署的相关信息(部署时间)

[3]act_re_procdef表

流程定义数据表,存储了当前流程图形的相关信息(id,name,版本号)

③解决乱码问题

import org.activiti.spring.SpringProcessEngineConfiguration;
import org.activiti.spring.boot.ProcessEngineConfigurationConfigurer;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ActivitiConfig implements ProcessEngineConfigurationConfigurer {

    @Override
    public void configure(SpringProcessEngineConfiguration processEngineConfiguration) {
        processEngineConfiguration.setActivityFontName("宋体");
        processEngineConfiguration.setLabelFontName("宋体");
    }

}

3.流程查询

①第一步:创建ProcessDefinitionQuery对象

    @Test
    public void test02ProcessDefinitionQuery() {
        //1.创建流程定义查询对象
        ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery();
        //2.调用对应的方法执行查询
        List<ProcessDefinition> list = query.list();
        //3.遍历集合
        for (ProcessDefinition processDefinition : list) {
            String key = processDefinition.getKey();
            String name = processDefinition.getName();
            int version = processDefinition.getVersion();
            
            System.err.println("key="+key);
            System.err.println("name="+name);
            System.err.println("version="+version);
        }
    }

注意2:创建了新的流程定义需要再次执行部署,再次启动流程。

6.查询任务和7.完成任务

@Test
    public void test03TaskQuery() {
        //创建任务查询对象
        TaskQuery query = taskService.createTaskQuery();
        //根据流程定义key和委托人查询待办任务
        List<Task> list = query.processDefinitionKey("MyProcess").taskAssignee("zuzu").list();
        for (Task task : list) {
            String assignee = task.getAssignee();
            String taskId = task.getId();
            String taskName = task.getName();
            //taskService需要使用@Autowired注解装配
            taskService.complete(task.getId());//完成任务,使任务进入下一步
            System.err.println("assignee="+assignee);
            System.err.println("taskId="+taskId);
            System.err.println("taskName="+taskName);
        }
    }

8.查询流程实例历史

//1.创建流程实例的历史查询对象,historyService使用@Autowired注解注入
HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery();
HistoricProcessInstance instance = 
		query.processInstanceId("7501")	//流程实例的id
			.finished()//调用这个方法后未完成的流程实例会返回null
			.singleResult();
System.out.println(instance);

9.将任务指派给一个组

注意1:创建的新的流程定义要指定一个新的id。
注意2:创建了新的流程定义需要再次执行部署,再次启动流程。

10.领取任务

    @Test
    public void test04Claim() {
        //1.创建任务查询对象
        TaskQuery taskQuery = taskService.createTaskQuery();
        //2.根据任务委托组查询任务列表
        List<Task> list = taskQuery.taskCandidateGroup("jingli").list();
        //3.遍历
        for (Task task : list) {
            String taskId = task.getId();
            String userId = "jingli";
            //3.指派任务
            taskService.claim(taskId, userId);
        }
    }

提示:可以根据任务委托人在领取任务前和领取任务后分别查询任务,之前没有之后有即为正确。

TaskQuery query = taskService.createTaskQuery();//创建任务查询对象
List<Task> list = query.processDefinitionKey("MyProcess")	//指定流程定义
			.taskAssignee("jingli")//指定委托人
			.list();//执行查询
for (Task task : list) {
	System.out.println(task);
}

11.流程变量

①在创建流程定义时指定流程变量

例如:用变量的方式指定委托人

创建MyProcess02.bpmn

创建后正常部署

    @Test
    public void test01ProcessDefinitionDeployment() {
        //部署:将流程定义文件中流程定义信息存入数据库
        repositoryService
            .createDeployment()     //创建部署构建器对象
            .addClasspathResource("MyProcess02.bpmn")   //添加要部署的流程定义文件名
            .deploy();      //执行部署
    }

②启动

    @Test
    public void test05StartProcessInstance() {
        //1.查询流程定义对象
        ProcessDefinition processDefinition = 
                repositoryService.createProcessDefinitionQuery()
                                 .processDefinitionKey("MyProcess02")
                                 .latestVersion()
                                 .singleResult();
        //2.获取流程定义的id
        String processDefinitionId = processDefinition.getId();
        //3.使用RunTimeService根据流程定义id启动流程定义
        ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinitionId);
        //4.打印processInstance对象
        System.err.println(processInstance);
        
    }

带有变量的流程启动时,如果第一个任务中就存在变量,那么启动的时候就必须给出变量值。否则将抛出异常:org.activiti.engine.impl.javax.el.PropertyNotFoundException: Cannot resolve identifier 'erzi'

    @Test
    public void test06StartProcessInstanceWithVariable() {
        //1.查询流程定义对象
        ProcessDefinition processDefinition = 
                repositoryService.createProcessDefinitionQuery()
                                 .processDefinitionKey("MyProcess02")
                                 .latestVersion()
                                 .singleResult();
        //2.获取流程定义的id
        String processDefinitionId = processDefinition.getId();
        //※为第一个任务指定流程变量
        Map<String,Object> variables = new HashMap<String, Object>();
        variables.put("erzi", "zhangsan");
        //3.使用RunTimeService根据流程定义id启动流程定义
        ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinitionId, variables);
        //4.打印processInstance对象
        System.err.println(processInstance);
    }

③完成任务

如果完成当前任务时,下一个任务中包含变量,那么此时也必须给出下一个任务的变量值

    @Test
    public void test7CompleteTaskWithVariables() {
        List<Task> list = 
                taskService.createTaskQuery() //创建任务查询对象
                           .processDefinitionKey("MyProcess02")//指定流程定义
                           .taskAssignee("zhangsan")//指定委托人
                           .list();//执行查询
        for (Task task : list) {
            String taskId = task.getId();
            //在完成当前任务时,为下一个任务指定流程变量
            Map<String,Object> variables = new HashMap<String, Object>();
            variables.put("sunzi", "lisi");
            //完成当前任务时为下一个任务指定变量值
            taskService.complete(taskId, variables);//完成任务,使任务进入下一步
            //Unknown property used in expression: ${sunzi}
            //taskService.complete(taskId);
        }
    }

12.排他网关

①创建流程定义

部署、启动

    @Test
    public void test01ProcessDefinitionDeployment() {
        //部署:将流程定义文件中流程定义信息存入数据库
        repositoryService
            .createDeployment()     //创建部署构建器对象
            .addClasspathResource("MyProcess03.bpmn")   //添加要部署的流程定义文件名
            .deploy();      //执行部署
    }
    @Test
    public void test05StartProcessInstance() {
        //1.查询流程定义对象
        ProcessDefinition processDefinition = 
                repositoryService.createProcessDefinitionQuery()
                                 .processDefinitionKey("MyProcess03")
                                 .latestVersion()
                                 .singleResult();
        //2.获取流程定义的id
        String processDefinitionId = processDefinition.getId();
        //3.使用RunTimeService根据流程定义id启动流程定义
        ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinitionId);
        //4.打印processInstance对象
        System.err.println(processInstance);
        
    }

②完成第一个任务时为排他网关指定变量值

    @Test
    public void test7CompleteTaskWithVariables() {
        List<Task> list = 
                taskService.createTaskQuery() //创建任务查询对象
                           .processDefinitionKey("MyProcess03")//指定流程定义
                           .taskAssignee("zhangsan")//指定委托人
                           .list();//执行查询
        for (Task task : list) {
            String taskId = task.getId();
            //在完成当前任务时,为下一个任务指定流程变量
            Map<String,Object> variables = new HashMap<String, Object>();
            variables.put("day", "5");
            //完成当前任务时为下一个任务指定变量值
            taskService.complete(taskId, variables);//完成任务,使任务进入下一步
            //Unknown property used in expression: ${sunzi}
            //taskService.complete(taskId);
        }
    }

[3]创建流程监听器类

import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.ExecutionListener;

public class YesListener implements ExecutionListener {

    private static final long serialVersionUID = 1L;

    @Override
    public void notify(DelegateExecution execution) throws Exception {
        System.err.println("YesListener触发了!!!");
    }

}
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.ExecutionListener;

public class NoListener implements ExecutionListener {

    private static final long serialVersionUID = 1L;

    @Override
    public void notify(DelegateExecution execution) throws Exception {
        System.err.println("NoListener触发了!!!");
    }

}

[4]绑定监听器

④操作

  • 部署
  •     /**
         * 部署
         */
        @Test
        public void test01ProcessDefinitionDeployment() {
            //部署:将流程定义文件中流程定义信息存入数据库
            repositoryService
                .createDeployment()     //创建部署构建器对象
                .addClasspathResource("MyProcess04.bpmn")   //添加要部署的流程定义文件名
                .deploy();      //执行部署
        }

     

  • 启动
  •     /**
         * 启动流程
         */
        @Test
        public void test05StartProcessInstance() {
            //1.查询流程定义对象
            ProcessDefinition processDefinition = 
                    repositoryService.createProcessDefinitionQuery()
                                     .processDefinitionKey("MyProcess04")
                                     .latestVersion()
                                     .singleResult();
            //2.获取流程定义的id
            String processDefinitionId = processDefinition.getId();
            //3.使用RunTimeService根据流程定义id启动流程定义
            ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinitionId);
            //4.打印processInstance对象
            System.err.println(processInstance);
            
        }

     

  • 完成任务时为排他网关指定flag变量值
  •     /**
         * 完成任务
         */
        @Test
        public void test7CompleteTaskWithVariables() {
            List<Task> list = 
                    taskService.createTaskQuery() //创建任务查询对象
                               .processDefinitionKey("MyProcess04")//指定流程定义
                               .taskAssignee("zhangsan")//指定委托人
                               .list();//执行查询
            for (Task task : list) {
                String taskId = task.getId();
                //在完成当前任务时,为下一个任务指定流程变量
                Map<String,Object> variables = new HashMap<String, Object>();
                variables.put("flag", "true");
                //完成当前任务时为下一个任务指定变量值
                taskService.complete(taskId, variables);//完成任务,使任务进入下一步
                //Unknown property used in expression: ${sunzi}
                //taskService.complete(taskId);
            }
        }

     

  • 观察监听器执行情况
Activity相关面试题 1、Activity的启动流程 Activity 启动主要涉及到3个进程: 系统进程 SystemServer (负责管理整个framework,是Zygote孵化的第一个进程) App进程(App进程是用户点击桌面icon时,通过Launcher进程请求SystemServer,再调用Zygote孵化的) Zygote进程(所有进程孵化都由Zygote完成,而Zygote是init进程的子进程,也由init进程孵化) 如果点击桌面icon启动还会涉及到 Launcher进程(Zygote孵化的第一个应用 阅读详情

相关推荐

Activiti工作流教程

Activiti是一个工作流引擎(其实就是一堆jar包API),业务系统访问(操作)activiti的接口,就可以方便的操作流程相关数据,这样就可以把工作流环境与业务系统的环境集成在一起。

qq_29384093的博客 1239

Activiti开源工作流引擎面试题

Activiti是一个开源的BPM(Business Process Management)框架,可以帮助企业实现业务流程的电子化和自动化。架构Activiti架构主要分为三部分:引擎、API和公共库。其中,引擎负责执行具体任务,API提供了对外的接口与应用整合,公共库则是在大量重复代码的基础上进行其他模块的扩展。引擎(Engine):Activiti核心是一个基于Java语言的流程引擎,其负责管理和执行整个流程的过程,并支持将业务数据和任务流程相结合。引擎包含两个核心组件:任务引擎和执行引擎。

yangzhihua的专栏 6376

Activiti工作流面试相关知识

Activiti 工作流面试相关知识 RepositoryService、RuntimeService、TaskService、HistoryService分别表示什么操作

Activiti面试题

流程定义是一个BPMN 2.0标准的XML文件,它描述了一个具体的工作流程,包括流程图、任务、网关、事件等。每个流程定义都具有唯一的标识符,可以多次实例化为流程实例,每个流程实例都是特定流程定义的一次执行。表单任务是Activiti中的用户任务,与用户交互的任务。Activiti的历史数据是指与流程执行相关的所有记录和数据,包括已完成的任务、流程实例、变量、时间戳等。是的,Activiti支持多租户模式,允许在单个Activiti引擎中为不同的租户或客户运行多个独立的流程。

koushen001的博客 2177

RK3568/RK3588之修改8250驱动实现RS485收发的自动切换

在串口发送前,若为485,则将控制引脚拉为发送状态,在发送后,循环查看是否发送完成,若发送完成则将引脚置回读状态,如此一来,就能实现在内核测控制方向切换,而不会因为延时造成数据丢失,经过测试此办法可行。全部修改完成后,重新编译生成内核文件和设备树文件,烧写到板子上即可。

哒宰的博客 3122

Navicat Premium 12 永久激活保姆级教程(附最新补丁下载)

本文详细介绍了Navicat Premium 12的高效使用方法,从安装配置到高级功能应用,帮助用户充分发挥这款数据库管理工具的全部潜力。内容包括数据库连接管理、数据查询与编辑、数据同步与结构对比等核心功能,以及性能优化和最佳实践建议,提升数据库管理效率。

weixin_28834765的博客 646

activiti工作流简介

  工作流简介 工作流定义 工作流:     就是“业务过程的部分或整体在计算机应用环境下的自动化”,它主要解决的是“使在多个参与者之间按照某种预定义的规则传递文档、信息或任务的过程自动进行,从而实现某个预期的业务目标,或者促使此目标的实现”。 工作流管理系统(Workflow Management System, WfMS):     工作流管理系统是一个软件系统,它完成工作量的定义...

m0_37683758的博客 1万+

NFS服务器配置与autofs自动挂载

NFS服务器配置autofs自动挂载 环境: hostname ip OS server 192.168.220.138 centos7 client 192.168.220.139 centos7 一、NFS概述 NFS(Network File System)网络文件系统。最大功能就是通过网络,让不同的机器、不同的操作系统可以共享彼此的文件。 二、端口 [root@se...

DoloresOOO的博客 1028

Activiti 工作流简介

工作流(Workflow),就是通过计算机对业务流程自动化执行管理。它主要解决的是“使在多个参与者之间按照某种预定义的规则自动进行传递文档、信息或任务的过程,从而实现某个预期的业务目标,或者促使此目标的实现”。

小石潭记丶 1万+

螺丝锁付系统软件设计 C# Winform

视觉螺丝锁付系统软件设计 C# Winform ,这是其中通信子模块设计

weixin_42522973的博客 340

Python学习24:中国古代数学问题——物不知数(Python123)

意思是说有一些物品,不知道有多少个,3个3个数的话,还多出2个;5个5个数则多出3个;7个7个数也会多出2个。题目为‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬:今有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二,问物几何?现假设物品总数不超过n (n

weixin_60530224的博客 2万+

Activiti工作流引擎

Activiti是一个工作流引擎, activiti可以将业务系统中复杂的业务流程抽取出来,使用专门的建模语言BPMN2.0进行定义,业务流程按照预先定义的流程进行执行,实现了系统的流程由activiti进行管理,减少业务系统由于流程变更进行系统升级改造的工作量,从而提高系统的健壮性,同时也减少了系统开发维护成本。.........

Hu_1991的博客 1万+

2026年(新服务器默认密码)最新各大厂商默认凭证大全

本文整理了国内外主流服务器厂商的默认管理接口凭证信息,包括Dell、HPE、浪潮、华为等品牌的管理接口类型、默认用户名/密码和IP地址。特别强调国产服务器在信创环境下的安全风险,指出国内厂商部分型号仍保留固定默认密码(如浪潮admin/admin),而国际厂商多采用随机密码标签。文章提供了新机初始化安全流程建议:查找机箱标签、立即修改默认密码、配置网络隔离、更新固件等。最后提醒运维人员,服务器安全应从首次上电开始重视,管理接口暴露是重大风险点,必须严格执行安全规范。

你好,旧时光! 1718

Activiti7工作流

Activiti工作流,生成表的步骤

m0_65941214的博客 1424

硬件基础(4):(7)ADC电压采集:软件校准(标定、拟合)

在实际项目中,**软件端校准**可以有效弥补硬件方面(分压电阻误差、放大器失调、参考源误差等)带来的系统性偏差,从而提高 ADC 测量精度。下面是一个常见的**多点实测校准**流程与思路,个人感觉传感器标定的原理也只这样。

FCZlll的博客 6248

从2804云台电机到桌面机械臂:一个STM32/GD32玩家的FOC驱动踩坑全记录

本文详细记录了从2804云台电机到桌面机械臂的FOC驱动开发历程,涵盖了硬件选型、驱动方案优化、软件调试等关键环节。特别分享了L6234P驱动芯片的发热问题、AS5600编码器的I2C通信陷阱以及PID调参的实战经验,为DIY爱好者提供了宝贵的参考。

weixin_26897585的博客 483

Activiti 工作流引擎

Activiti 工作流引擎

wang的博客 4471

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

activiti工作流

demo下载 链接: https://pan.baidu.com/s/15b-YYoS99AMBO8s4lIewgg 提取码: 7v98 一、为什么选择Activiti 工作流引擎对比 二、核心7大接口、28张表 7大接口 (一)7大接口 RepositoryService:提供一系列管理流程部署和流程定义的API。 RuntimeService:在流程运行时对流程实例...

FREEDOM 1454

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

Activiti工作流浅析

新钛云服已累计为您分享695篇技术干货一、工作流1、工作流概述在一个公司业务中,每一个业务的开始和结束,都可以理解成为一个工作流。例如公司请假的基本流程。如图所示,员工先提出请假申请,提交该申请给直属领导审批,直属领导审批后,再提交给人事部门审批,审批完成后,通知提出申请的员工,即请假流程结束。整个步骤按照正常工作方式一步步完成,这就是一个简单而又完整的工作流;工作流可以理解为从开始节点发起流程,...

NewTyun的博客 1344

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

上一篇: Spring Cloud:第一章:基本介绍
下一篇: James邮件服务器
Java程序员廖志伟
Java程序员廖志伟 优质创作者: Java技术领域 优质创作者: Java技术领域 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄8年 2万+粉丝 1902原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java程序员廖志伟

赏我包辣条呗

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值