一切福田,不離方寸,從心而覓,感無不通。

Category Archives: Backend

docker自动启动容器

Docker提供了重新启动策略 来控制容器在退出时或Docker重新启动时是否自动启动。重新启动策略可确保以正确的顺序启动链接的容器。Docker建议您使用重新启动策略,并避免使用进程管理器来启动容器。 重新启动策略--live-restore与dockerd 命令的标志不同。--live-restore尽管网络和用户输入中断,但使用允许您在Docker升级期间保持容器运行。 使用重启策略 要为容器配置重新启动策略,请--restart在使用该docker run命令时使用该标志。--restart标志的值可以是以下任何一种: 旗 描述 no 不要自动重启容器。(默认) on-failure 如果容器由于错误而退出,则重新启动容器,该错误表现为非零退出代码。 always 如果容器停止,请务必重启容器。如果手动停止,则仅在Docker守护程序重新启动或手动重新启动容器本身时才重新启动。(参见重启政策详情中列出的第二个项目) unless-stopped 类似于always,除了当容器停止(手动或其他方式)时,即使在Docker守护程序重新启动后也不会重新启动容器。 以下示例启动Redis容器并将其配置为始终重新启动,除非明确停止或重新启动Docker。

  重启政策详情 使用重启策略时请记住以下几点: 重启策略仅在容器成功启动后生效。在这种情况下,成功启动意味着容器启动至少10秒并且Docker已开始监视它。这可以防止根本不启动的容器进入重启循环。 如果手动停止容器,则会忽略其重新启动策略,直到Docker守护程序重新启动或手动重新启动容器。这是防止重启循环的另一种尝试。 重新启动策略仅适用于容器。群组服务的重新启动策略配置不同。请参阅与服务重新启动相关的 标志。 如果run时没有添加restart 可以通过update命令追加 docker update --restart=always web 1、先后台启动容器未加restart参数 2、docker ps 查看了当前运行的容器 3、重启docker 服务 4、再次docker ps 查看当前运行的容器,发现容器并没有运行 5、利用 update 设置 restart=always 6、重启docker 服务 7、再次docker ps 查看当前运行的容器,此时发现已经自动启动容器 ——————— 使用流程管理器 如果重新启动策略不适合您的需要,例如当Docker之外的进程依赖Docker容器时,您可以使用流程管理器,例如 upstart, systemd或supervisor。 警告:不要尝试将Docker重新启动策略与主机级进程管理器结合使用,因为这会产生冲突。 要使用进程管理器,请将其配置为使用您通常用于手动启动容器的相同docker start或docker service命令来启动容器或服务。有关更多详细信息,请参阅特定流程管理器的文档。 在容器内使用进程管理器 进程管理器也可以在容器内运行,以检查进程是否正在运行,如果没有则启动/重启进程   官方介绍在此,以上内容引用官网内容 https://docs.docker.com/engine/admin/start-containers-automatically/#use-a-process-manager   from:https://www.cnblogs.com/wei9593/p/11192908.html

龙生   26 Oct 2021
View Details

RabbitMQ中 exchange、route、queue的关系

从AMQP协议可以看出,MessageQueue、Exchange和Binding构成了AMQP协议的核心,下面我们就围绕这三个主要组件    从应用使用的角度全面的介绍如何利用Rabbit MQ构建消息队列以及使用过程中的注意事项。     1. 声明MessageQueue 在Rabbit MQ中,无论是生产者发送消息还是消费者接受消息,都首先需要声明一个MessageQueue。这就存在一个问题,是生产者声明还是消费者声明呢?要解决这个问题,首先需要明确: a)消费者是无法订阅或者获取不存在的MessageQueue中信息。 b)消息被Exchange接受以后,如果没有匹配的Queue,则会被丢弃。 在明白了上述两点以后,就容易理解如果是消费者去声明Queue,就有可能会出现在声明Queue之前,生产者已发送的消息被丢弃的隐患。如果应用能够通过消息重发的机制允许消息丢失,则使用此方案没有任何问题。但是如果不能接受该方案,这就需要无论是生产者还是消费者,在发送或者接受消息前,都需要去尝试建立消息队列。这里有一点需要明确,如果客户端尝试建立一个已经存在的消息队列,Rabbit MQ不会做任何事情,并返回客户端建立成功的。 如果一个消费者在一个信道中正在监听某一个队列的消息,Rabbit MQ是不允许该消费者在同一个channel去声明其他队列的。Rabbit MQ中,可以通过queue.declare命令声明一个队列,可以设置该队列以下属性: a) Exclusive:排他队列,如果一个队列被声明为排他队列,该队列仅对首次声明它的连接可见,并在连接断开时自动删除。这里需要注意三点:其一,排他队列是基于连接可见的,同一连接的不同信道是可以同时访问同一个连接创建的排他队列的。其二,“首次”,如果一个连接已经声明了一个排他队列,其他连接是不允许建立同名的排他队列的,这个与普通队列不同。其三,即使该队列是持久化的,一旦连接关闭或者客户端退出,该排他队列都会被自动删除的。这种队列适用于只限于一个客户端发送读取消息的应用场景。 b)   Auto-delete:自动删除,如果该队列没有任何订阅的消费者的话,该队列会被自动删除。这种队列适用于临时队列。 c)   Durable:持久化,这个会在后面作为专门一个章节讨论。 d)  其他选项,例如如果用户仅仅想查询某一个队列是否已存在,如果不存在,不想建立该队列,仍然可以调用queue.declare,只不过需要将参数passive设为true,传给queue.declare,如果该队列已存在,则会返回true;如果不存在,则会返回Error,但是不会创建新的队列。 2. 生产者发送消息 在AMQP模型中,Exchange是接受生产者消息并将消息路由到消息队列的关键组件。ExchangeType和Binding决定了消息的路由规则。所以生产者想要发送消息,首先必须要声明一个Exchange和该Exchange对应的Binding。可以通过 ExchangeDeclare和BindingDeclare完成。在Rabbit MQ中,声明一个Exchange需要三个参数:ExchangeName,ExchangeType和Durable。ExchangeName是该Exchange的名字,该属性在创建Binding和生产者通过publish推送消息时需要指定。ExchangeType,指Exchange的类型,在RabbitMQ中,有三种类型的Exchange:direct ,fanout和topic,不同的Exchange会表现出不同路由行为。Durable是该Exchange的持久化属性,这个会在消息持久化章节讨论。声明一个Binding需要提供一个QueueName,ExchangeName和BindingKey。下面我们就分析一下不同的ExchangeType表现出的不同路由规则。 生产者在发送消息时,都需要指定一个RoutingKey和Exchange,Exchange在接到该RoutingKey以后,会判断该ExchangeType: a) 如果是Direct类型,则会将消息中的RoutingKey与该Exchange关联的所有Binding中的BindingKey进行比较,如果相等,则发送到该Binding对应的Queue中。     b)   如果是  Fanout  类型,则会将消息发送给所有与该  Exchange  定义过  Binding  的所有  Queues  中去,其实是一种广播行为。     c)如果是Topic类型,则会按照正则表达式,对RoutingKey与BindingKey进行匹配,如果匹配成功,则发送到对应的Queue中。   3. 消费者订阅消息 在RabbitMQ中消费者有2种方式获取队列中的消息: a)  一种是通过basic.consume命令,订阅某一个队列中的消息,channel会自动在处理完上一条消息之后,接收下一条消息。(同一个channel消息处理是串行的)。除非关闭channel或者取消订阅,否则客户端将会一直接收队列的消息。 b)  另外一种方式是通过basic.get命令主动获取队列中的消息,但是绝对不可以通过循环调用basic.get来代替basic.consume,这是因为basic.get RabbitMQ在实际执行的时候,是首先consume某一个队列,然后检索第一条消息,然后再取消订阅。如果是高吞吐率的消费者,最好还是建议使用basic.consume。 如果有多个消费者同时订阅同一个队列的话,RabbitMQ是采用循环的方式分发消息的,每一条消息只能被一个订阅者接收。例如,有队列Queue,其中ClientA和ClientB都Consume了该队列,MessageA到达队列后,被分派到ClientA,ClientA服务器收到响应,服务器删除MessageA;再有一条消息MessageB抵达队列,服务器根据“循环推送”原则,将消息会发给ClientB,然后收到ClientB的确认后,删除MessageB;等到再下一条消息时,服务器会再将消息发送给ClientA。 这里我们可以看出,消费者再接到消息以后,都需要给服务器发送一条确认命令,这个即可以在handleDelivery里显示的调用basic.ack实现,也可以在Consume某个队列的时候,设置autoACK属性为true实现。这个ACK仅仅是通知服务器可以安全的删除该消息,而不是通知生产者,与RPC不同。 如果消费者在接到消息以后还没来得及返回ACK就断开了连接,消息服务器会重传该消息给下一个订阅者,如果没有订阅者就会存储该消息。 既然RabbitMQ提供了ACK某一个消息的命令,当然也提供了Reject某一个消息的命令。当客户端发生错误,调用basic.reject命令拒绝某一个消息时,可以设置一个requeue的属性,如果为true,则消息服务器会重传该消息给下一个订阅者;如果为false,则会直接删除该消息。当然,也可以通过ack,让消息服务器直接删除该消息并且不会重传。 4. 持久化: Rabbit MQ默认是不持久队列、Exchange、Binding以及队列中的消息的,这意味着一旦消息服务器重启,所有已声明的队列,Exchange,Binding以及队列中的消息都会丢失。通过设置Exchange和MessageQueue的durable属性为true,可以使得队列和Exchange持久化,但是这还不能使得队列中的消息持久化,这需要生产者在发送消息的时候,将delivery mode设置为2,只有这3个全部设置完成后,才能保证服务器重启不会对现有的队列造成影响。这里需要注意的是,只有durable为true的Exchange和durable为ture的Queues才能绑定,否则在绑定时,RabbitMQ都会抛错的。持久化会对RabbitMQ的性能造成比较大的影响,可能会下降10倍不止。 5. 事务: 对事务的支持是AMQP协议的一个重要特性。假设当生产者将一个持久化消息发送给服务器时,因为consume命令本身没有任何Response返回,所以即使服务器崩溃,没有持久化该消息,生产者也无法获知该消息已经丢失。如果此时使用事务,即通过txSelect()开启一个事务,然后发送消息给服务器,然后通过txCommit()提交该事务,即可以保证,如果txCommit()提交了,则该消息一定会持久化,如果txCommit()还未提交即服务器崩溃,则该消息不会服务器就收。当然Rabbit MQ也提供了txRollback()命令用于回滚某一个事务。 6. Confirm机制: 使用事务固然可以保证只有提交的事务,才会被服务器执行。但是这样同时也将客户端与消息服务器同步起来,这背离了消息队列解耦的本质。Rabbit MQ提供了一个更加轻量级的机制来保证生产者可以感知服务器消息是否已被路由到正确的队列中——Confirm。如果设置channel为confirm状态,则通过该channel发送的消息都会被分配一个唯一的ID,然后一旦该消息被正确的路由到匹配的队列中后,服务器会返回给生产者一个Confirm,该Confirm包含该消息的ID,这样生产者就会知道该消息已被正确分发。对于持久化消息,只有该消息被持久化后,才会返回Confirm。Confirm机制的最大优点在于异步,生产者在发送消息以后,即可继续执行其他任务。而服务器返回Confirm后,会触发生产者的回调函数,生产者在回调函数中处理Confirm信息。如果消息服务器发生异常,导致该消息丢失,会返回给生产者一个nack,表示消息已经丢失,这样生产者就可以通过重发消息,保证消息不丢失。Confirm机制在性能上要比事务优越很多。但是Confirm机制,无法进行回滚,就是一旦服务器崩溃,生产者无法得到Confirm信息,生产者其实本身也不知道该消息吃否已经被持久化,只有继续重发来保证消息不丢失,但是如果原先已经持久化的消息,并不会被回滚,这样队列中就会存在两条相同的消息,系统需要支持去重。   其他: Broker:简单来说就是消息队列服务器实体。 Exchange:消息交换机,它指定消息按什么规则,路由到哪个队列。 Queue:消息队列载体,每个消息都会被投入到一个或多个队列。 Binding:绑定,它的作用就是把exchange和queue按照路由规则绑定起来。 Routing Key:路由关键字,exchange根据这个关键字进行消息投递。 vhost:虚拟主机,一个broker里可以开设多个vhost,用作不同用户的权限分离。 producer:消息生产者,就是投递消息的程序。 consumer:消息消费者,就是接受消息的程序。 channel:消息通道,在客户端的每个连接里,可建立多个channel,每个channel代表一个会话任务。 消息队列的使用过程大概如下: (1)客户端连接到消息队列服务器,打开一个channel。 (2)客户端声明一个exchange,并设置相关属性。 (3)客户端声明一个queue,并设置相关属性。 (4)客户端使用routing key,在exchange和queue之间建立好绑定关系。 (5)客户端投递消息到exchange。   Exchanges, queues, and bindings   […]

龙生   26 Oct 2021
View Details

IDEA 停止在 Synchronizing output directories

重新Rubuild Project   停止在   运行时错误:     试着的解决方式    运行clean 、install  、运行。 运行正常!!   解决方法 删除 .idea ,重新打开项目 ,重新建立工程Rebuild Project ,信息如下: java: /E:/JPADemo/src/main/java/com/example/jpademo/JpaDemoApplication.java使用了未经检查或不安全的操作。 要取消这种告警信息,可在 public class JpaDemoApplication 类面前加@SuppressWarnings("unchecked")   原因:JAVA是一门安全性比较高的语言,它在编译之类要进行类型等一系列的检查。如果你使用了注解就可以告诉编译器不用检查,这样子就可以避过编译时期间的安全检查,这样子的效率会提高 。但同时 安全性就大打折扣了。 但是运行正常!!   from:https://www.cnblogs.com/wfy680/p/15014376.html

龙生   24 Oct 2021
View Details

使用IntelliJ IDEA 体验Groovy开发

使用IntelliJ IDEA开发groovy,创建一个项目进入到这个界面: 如果Groovy. library是no. library select 那就点击右侧的create按钮,选择你安装的groovy目录就可以, 如果IntelliJ IDEA 左侧没有Groovy选项的话那就安装groovy插件, 新建的groovy项目是这样的: 会发现并不是像我们Android 在studio下创建项目一样有一个默认的MainActivity,groovy是没有的,那么从事编程开发的入门都是从hello world开始的,那么现在创建一个hello.groovy文件

  这是我们创建的第一个类Hello.groovy 从上面的代码就可以提现出groovy是完全支持Java的 而且更方便的是我们在控制台输入一句话 直接使用println()方法就行,相当于Java中的静态导包功能. 还有更神奇的写法: 是不是groovy很强大 这个写法和上面的Java中的写法结果是一样的.如果想弄懂gradle 构建是有必须去学习下.   from:https://blog.csdn.net/coderinchina/article/details/89600861

龙生   22 Oct 2021
View Details

idea报错Cannot compile Groovy files: no Groovy library is defined for module 'xx’之方

0、病因描写 clone 原有的项目(新建的项目一般不会有) IntelliJ IDEA 关联了后缀为groovy的文件但是没有配置Groovy的library。 1、病因一之解决方法 病因:本项目不需要用的Groovy但是关联了groovy了文件 方子:那直接去掉后缀为groovy的关联即可 结果:良好,网上基本都是这种方子 如图:去掉红框部分并apply 2、病因二之解决之法 病因:项目需要groovy的library。 方子:那就是配置groovy的library咯。 步骤: ①、下载groovy library ②、解压(选一个中意的目录,最好目录路径是全英文的) ③、配置groovy library:File —>Project Structure —> Modules —> Groovy —> Add Groovy Support —> 选择 Groovy library 最后 apply就OK了。 如图: 快捷配置入口:如果IDEA有如下提示就最好了–方便。直接点击 Configuration Groovy SDK 即可。   from:https://www.2cto.com/kf/201803/732193.html

龙生   21 Oct 2021
View Details

NuGet修改默认包保存的位置

NuGet默认的全局包下载地址一般为:C:\Users\{username}\.nuget\packages     修改方法:  

  from:https://www.cnblogs.com/sword88/p/11490304.html

龙生   19 Oct 2021
View Details

springboot整合mongodb,并配置账户名和密码登录验证

springboot pom.xml加入依赖

application.yml加入连接信息 mapper编写

Application启动添加注解

application.yml配置,这里之前碰到一个坑,mongodb的配置没有写host和port属性,只写了database和uri,这种方式在无密码验证的情况下,可以连接mongodb。但是在mongodb设置了密码登录后,就无法连接,一直提示 Caused by: com.mongodb.MongoCommandException: Command failed with error 13: 'not authorized on wxsb_dev to execute command { insert 这里我们说下,application.yml关于mongodb的两种配置 第一种,yml方式,注意这里的host port username password database,每个属性都要配置。

  第二种,uri方式

  之前就是配了如下的参数,导致一直出错,还以为是mongodb的用户权限配置出错导致,原来是配置文件出错,报错信息 Caused by: com.mongodb.MongoCommandException: Command failed with error 13: 'not authorized on wxsb_dev to execute command { insert

  from:https://www.it610.com/article/1283088113266081792.htm

龙生   18 Oct 2021
View Details

用docker部署RabbitMQ环境

前置条件: 已经安装好docker 1.查找镜像(有2种方式) ①登录rabbitmq官网找到docker镜像,选择想要的镜像的tag https://www.rabbitmq.com/download.html https://hub.docker.com/_/rabbitmq 如果需要访问web管理页面,就选择tag为management的 ps:带有alpine的是用最小linux镜像构建的,体积最小可以达5M初学者不建议这么折腾,而且 Alpine Linux使用了muslmusl实现的DNS服务不会使用resolv.conf文件中的search和domain两个配置,通过DNS来进行服务发现时需要注意。,带有-management的是带有web控制台   ②直接用docker search 搜索,默认下载标签为latest的镜像(无法打开web管理页面)

ps:如果是普通用户登录,需要sudo,不然会提示错误

2.下载镜像(有时候网络问题超时,多尝试几次即可。我这里选择的是可以访问web管理界面的tag)

3.创建容器并运行(15672是管理界面的端口,5672是服务的端口。这里顺便将管理系统的用户名和密码设置为admin admin)

  from:https://www.cnblogs.com/yy-cola/p/11089800.html

龙生   18 Oct 2021
View Details

这个开源组织里的项目都是精品

前言 在开源中国里,不知道大家有没有留意到一个Java开源组织——Dromara? 这个组织是由Apache ShenYu(前身是Soul网关)的作者创立,多位Java开源作者参与的一个Java开源组织。 在开源中国社区,很多Java开源作者都是各自为战,独立运营项目。Domara组织的诞生就是为了联合Java开源的力量,共建社区,资源共享,共同推行中国Java开源事业的发展。 目前Dromara社区拥有9个GVP项目,和一些Star数量很高的项目。这些开源项目社区都很活跃,每一个都是能提高工作效率的精品开源作品。下面就来盘点下Dromara组织其中的4个开源项目。都是非常实用的工具,用好这些将会让你的生产效率大大提升! Sa-Token 首先我要介绍的是Sa-Token,可能是史上功能最全的轻量级 Java 权限认证框架。 简单的使用方式,丰富的特性,强大的功能,你有什么理由拒绝? 官方网站:sa-token.dev33.cn/ Gitee托管仓库:gitee.com/dromara/sa-… Github托管仓库:github.com/dromara/Sa-… Sa-Token 是一个轻量级 Java 权限认证框架,主要解决:登录认证、权限认证、Session会话、单点登录、OAuth2.0、微服务网关鉴权 等一系列权限相关问题。 Sa-Token 的 API 设计非常简单,有多简单呢?以登录认证为例,你只需要:

  至此,我们已经借助 Sa-Token 完成登录认证! 此时的你小脑袋可能飘满了问号,就这么简单?自定义 Realm 呢?全局过滤器呢?我不用写各种配置文件吗? 没错,在 Sa-Token 中,登录认证就是如此简单,不需要任何的复杂前置工作,只需这一行简单的API调用,就可以完成会话登录认证! 当你受够 Shiro、SpringSecurity 等框架的三拜九叩之后,你就会明白,相对于这些传统老牌框架,Sa-Token 的 API 设计是多么的简单、优雅! 权限认证示例(只有具备 user:add 权限的会话才可以进入请求)

  将某个账号踢下线(待到对方再次访问系统时会抛出NotLoginException异常)

  在 Sa-Token 中,绝大多数功能都可以 一行代码 完成:

  即使不运行测试,相信您也能意会到绝大多数 API 的用法。 想要了解更多请参考:gitee.com/dromara/sa-… Forest 一款极大程度解放你的Http接入工作的强大Http客户端框架。 Http协议很复杂吗?那是因为你还没有使用过Forest,虽然业内有很多其他优秀的Http客户端,但是你错过了Forest,将会错过一大片优雅美丽的森林。 官方网站:forest.dtflyx.com Gitee托管仓库:gitee.com/dromara/for… Github托管仓库:github.com/dromara/for… Forest 是一个开源的 Java HTTP 客户端框架,用来访问第三方服务 RESTful 接口。 它能够将 HTTP 的请求参数绑定到 Java 接口上,之后调用 Java 接口就等于在发送 HTTP 请求。一切面向于接口。 很多公司需要在 Java 后台调用许多第三方 HTTP 接口,比如微信支付、友盟等等第三方平台。 公司内部还有很多服务是用世界最好语言写的,接口自然也只能通过 HTTP […]

龙生   13 Oct 2021
View Details

横空出世!IDEA画图神器来了,比Visio快10倍!

程序员在工作中,经常会有绘制时序图、流程图的需求,尤其是在写文档的时候。平时我们会选择ProcessOn这类工具来绘制,但有时候用代码来画图可能会更高效一点,毕竟没有比程序员更熟悉代码的了。今天给大家推荐一款画图工具PlantUML,可以配合IDEA使用,画图更高效! SpringBoot实战电商项目mall(50k+star)地址:github.com/macrozheng/… PlantUML简介 PlantUML是一款开源的UML图绘制工具,支持通过文本来生成图形,使用起来非常高效。可以支持时序图、类图、对象图、活动图、思维导图等图形的绘制。 下面使用PlantUML来绘制一张流程图,可以实时预览,速度也很快! 安装 通过在IDEA中安装插件来使用PlantUML无疑是最方便的,接下来我们来安装下IDEA的PlantUML插件。 首先在IDEA的插件市场中搜索PlantUML,安装这个排名第一的插件; 有时候网络不好的话可能下载不下来,可以点击Plguin homepage按钮访问插件主页,然后选择合适的版本下载压缩包; 下载成功后,选择从本地安装即可。 使用 接下来我们使用PlantUML插件分别绘制时序图、用例图、类图、活动图、思维导图,来体验下PlantUML是不是真的好用! 时序图 时序图(Sequence Diagram),是一种UML交互图。它通过描述对象之间发送消息的时间顺序显示多个对象之间的动态协作。我们在学习Oauth2的时候,第一步就是要搞懂Oauth2的流程,这时候有个时序图帮助可就大了。下面我们使用PlantUML来绘制Oauth2中使用授权码模式颁发令牌的时序图。 首先我们需要新建一个PlantUML文件,选择时序图; 我们可以通过PlantUML提供的语法来生成Oauth2的时序图,语法还是非常简单的,具体内容如下;

该代码将生成如下时序图,用写代码的方式来画时序图,是不是够炫酷; 本时序图关键说明如下: title可以用于指定UML图的标题; 通过actor可以声明人形的参与者; 通过participant可以声明普通类型的参与者; 通过as可以给参与者取别名; 通过->可以绘制参与者之间的关系,虚线箭头可以使用-->; 在每个参与者关系后面,可以使用:给关系添加说明; 通过autonumber我们可以给参与者关系自动添加序号; 通过activate和deactivate可以指定参与者的生命线。 这里还有个比较神奇的功能,当我们右键时序图时,可以生成一个在线访问的链接; 直接访问这个链接,可以在线访问UML时序图,并进行编辑,是不是很酷! 用例图 用例图(Usecase Diagram)是用户与系统交互的最简表示形式,展现了用户和与他相关的用例之间的关系。通过用例图,我们可以很方便地表示出系统中各个角色与用例之间的关系,下面我们用PlantUML来画个用例图。 首先我们需要新建一个PlantUML文件,选择用例图,该用例图用于表示顾客、主厨、美食家与餐馆中各个用例之间的关系,具体内容如下;

该代码将生成如下用例图; 本用例图关键说明如下: left to right direction表示按从左到右的顺序绘制用例图,默认是从上到下; 通过package可以对角色和用例进行分组; 通过actor可以定义用户; 通过usecase可以定义用例; 角色和用例之间的关系可以使用-->来表示。 类图 类图(Class Diagram)可以表示类的静态结构,比如类中包含的属性和方法,还有类的继承结构。下面我们用PlantUML来画个类图。 首先我们需要新建一个PlantUML文件,选择类图,该图用于表示Person、Student、Teacher类的结构,具体内容如下;

该代码将生成如下类图,看下代码和类图,是不是发现和我们用代码定义类还挺像的; 本类图关键说明如下: 通过class可以定义类; 通过在属性和方法左边加符号可以定义可见性,-表示private,#表示protected,+表示public; 通过<|--表示类之间的继承关系。 活动图 活动图(Activity Diagram)是我们用的比较多的UML图,经常用于表示业务流程,比如电商中的下单流程就可以用它来表示。下面我们用PlantUML来画个活动图。 首先我们需要新建一个PlantUML文件,选择活动图,这里使用了mall项目中购物车中生成确认单的流程,具体内容如下;

该代码将生成如下活动图,在活动图中我们既可以用if else,又可以使用switch,甚至还可以使用while循环,功能还是挺强大的; 本活动图关键说明如下: 通过start和stop可以表示流程的开始和结束; 通过:和;中间添加文字来定义活动流程节点; 通过if+then+endif定义条件判断; 通过switch+case+endswitch定义switch判断。 思维导图 思维导图(Mind Map),是表达发散性思维的有效图形工具,它简单却又很有效,是一种实用性的思维工具。之前在我的mall学习教程中就有很多地方用到了,下面我们用PlantUML来画个思维导图。 首先我们需要新建一个PlantUML文件,选择思维导图,这里使用了mall学习路线中的大纲视图,具体内容如下;

该代码将生成如下思维导图,其实使用PlantUML我们可以自己定义图形的样式,这里我自定义了下颜色; 本思维导图关键说明如下: 通过+和-可以表示思维导图中的节点,具有方向性; 通过[#颜色]可以定义节点的边框颜色; 通过_可以去除节点的边框; 总结 虽然目前可以绘制UML图的图形化工具很多,但是对于程序员来说,使用代码来绘图可能更直接,效率更高,尤其是配合IDEA使用。如果你想使用代码来绘图,不妨尝试下PlantUML吧。 参考资料 官方文档:plantuml.com/zh/ 作者:MacroZheng 链接:https://juejin.cn/post/7017988314053492767 来源:稀土掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

龙生   13 Oct 2021
View Details
1 56 57 58 281