当前位置: 首页 > news >正文

Android详解——ConstraintLayout约束布局

目录

一、ConstraintLayout概述

二、ConstraintLayout属性介绍

1. 相对位置

2. 边距

3. 中心和偏移位置

中心位置

偏移位置

4. 圆形位置

5. 可见性

6. 尺寸约束

最小尺寸

WRAP_CONTENT :强制约束

MATCH_CONSTRAINT

Min和Max

百分比尺寸

比率

7. 链式布局

创建链条

链条头

链条边距

链条风格

权重链

边距

8. 虚拟辅助控件

9. 优化器


一、ConstraintLayout概述

ConstraintLayout继承自ViewGroup,允许用户以更加灵活的方式在布局中设置控件的位置和尺寸。(ConstraintLayout在API>9可用)

二、ConstraintLayout属性介绍

ConstraintLayout功能有如下几种:

  • 相对位置
  • 边距
  • 中心位置
  • 圆形位置
  • 可见性
  • 尺寸约束
  • 链式布局
  • 虚拟辅助控件
  • 优化器

记住,依赖关系中不能有循环依赖关系。

1. 相对位置

类似于RelativeLayout功能。

相对位置功能是约束布局中构建控件位置的最基本的功能之一。相对位置约束条件可以定位一个控件相对于另一个控件的位置。可以限定一个控件在水平和垂直坐标轴上的位置:

  • Horizontal 轴: left, right, start and end sides

  • Vertical 轴: top, bottom sides and text baseline

通常是指一个控件限定在另一个控件边缘的位置。

例如:

        <Button android:id="@+id/buttonA" ... /><Button android:id="@+id/buttonB" ...app:layout_constraintLeft_toRightOf="@+id/buttonA" />

上述代码限定按钮B在按钮A的右边。按钮B的左边和按钮A的右边在相同的位置。

相对位置约束属性有如下几个:

  • layout_constraintLeft_toLeftOf

  • layout_constraintLeft_toRightOf

  • layout_constraintRight_toLeftOf

  • layout_constraintRight_toRightOf

  • layout_constraintTop_toTopOf

  • layout_constraintTop_toBottomOf

  • layout_constraintBottom_toTopOf

  • layout_constraintBottom_toBottomOf

  • layout_constraintBaseline_toBaselineOf

  • layout_constraintStart_toEndOf

  • layout_constraintStart_toStartOf

  • layout_constraintEnd_toStartOf

  • layout_constraintEnd_toEndOf

约束对象可以通过另一个控件的属性id设置,也可以设置父布局parent

例如:

        <Button android:id="@+id/buttonB" ...app:layout_constraintLeft_toLeftOf="parent" />

2. 边距

如果控件的边距可以设置,那么边距可用于约束布局。约束两个控件之间的边距大小。通用的边距属性有如下几种:

  • android:layout_marginStart

  • android:layout_marginEnd

  • android:layout_marginLeft

  • android:layout_marginTop

  • android:layout_marginRight

  • android:layout_marginBottom

  • layout_marginBaseline

记住,边距只能>=0,采用维度设置。

3. 中心和偏移位置

中心位置

水平中心位置如下:

        <androidx.constraintlayout.widget.ConstraintLayout ...><Button android:id="@+id/button" ...app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"/></>

垂直中心位置类似top和bottom设置。

偏移位置

相对于左右水平偏移量,或者相对于上下位置的垂直偏移量。

例如:相对于水平偏移0.3

        <androidx.constraintlayout.widget.ConstraintLayout ...><Button android:id="@+id/button" ...app:layout_constraintHorizontal_bias="0.3"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"/></>

4. 圆形位置

可以限定一个控件中心相对于另一个控件中心的角度和距离。可以在一个圆上设置控件。可用属性如下:

  • layout_constraintCircle : 设置参考的控件id
  • layout_constraintCircleRadius : 设置控件中心相对于另一个控件中心的距离
  • layout_constraintCircleAngle : 设置相对于另一个控件的角度(角度范围:0~360)

例如:

 <Button android:id="@+id/buttonA" ... /><Button android:id="@+id/buttonB" ...app:layout_constraintCircle="@+id/buttonA"app:layout_constraintCircleRadius="100dp"app:layout_constraintCircleAngle="45" />

5. 可见性

6. 尺寸约束

最小尺寸

可以定义约束布局的最小和最大尺寸:

  • android:minWidth 设置布局的最小宽度

  • android:minHeight 设置布局的最小高度

  • android:maxWidth 设置布局的最大宽度

  • android:maxHeight 设置布局的最大高度

当布局被设置成WRAP_CONTENT时,这些最小和最大的维度可以被用于布局中。

控件维度大小可以通过android:layout_width and android:layout_height 来设置,有3种不同的设置方式:

  • 用具体的维度值(例如用数值123dp或者维度参考值)

  • WRAP_CONTENT,是请求计算应用控件本身的尺寸

  • 0dp, 等于"MATCH_CONSTRAINT"

前两种布局的工作方式与其他布局相似。最后一个将调整小部件的大小,使其与设置的约束相匹配。如果设置了边距,它们将在计算中被考虑在内。

重点: MATCH_PARENT 不被推荐在ConstraintLayout布局中使用. 类似的设置可以用 MATCH_CONSTRAINT,相对于left/right或者top/bottom的约束是基于父布局“parent”.

WRAP_CONTENT :强制约束

尺寸设置为WRAP_CONTENT, 在1.1版本之前,这是文字尺寸。这意味着不会限制结果尺寸。当某些情况下可用 WRAP_CONTENT限制结果尺寸,此时可以添加相应的属性设置:

  • app:layout_constrainedWidth="true|false"

  • app:layout_constrainedHeight="true|false"

layout_constrainedWidth是 Android 中 ConstraintLayout 布局管理器的一个属性,用于控制当控件的尺寸设置为 wrap_content 时,是否应受约束限制其宽度。以下是关于 layout_constrainedWidth的详细解释:

  • layout_constrainedWidth在 Android 布局中的含义

layout_constrainedWidth属性用于指定当控件的宽度设置为 wrap_content 时,是否应该受到其在 ConstraintLayout 中的水平约束限制。在 Android ConstraintLayout 的 1.1 版本之前,如果控件的宽度设置为 wrap_content,则约束对其宽度没有影响。而 layout_constrainedWidth属性的引入,使得即使在 wrap_content 模式下,控件的宽度也会受到约束限制。

  • layout_constrainedWidth属性的使用场景

当你在 ConstraintLayout 中使用 wrap_content 来设置控件的宽度,并且希望这个宽度受到其他控件或父布局的约束时,可以使用 layout_constrainedWidth属性。特别是在处理文本控件(如 TextView)时,如果文本内容可能非常长,使用 layout_constrainedWidth可以确保文本不会溢出其约束范围。

  • layout_constrainedWidth属性可以接受的值及其效果

true:控件的宽度将受到其水平约束的限制,即使控件的宽度设置为 wrap_content。
false(默认值):控件的宽度将不会受到其水平约束的限制,即使设置了约束。

  • 如何在 XML 布局文件中设置 layout_constrainedWidth属性的示例
<TextViewandroid:id="@+id/myTextView"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="这是一个很长的文本,用于测试 layout_constrainedwidth 属性"app:layout_constrainedWidth="true"app:layout_constraintStart_toStartOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintTop_toTopOf="parent"app:layout_constraintBottom_toBottomOf="parent"android:ellipsize="end"android:maxLines="1"/>


在这个例子中,TextView 的宽度被设置为 wrap_content,但由于 app:layout_constrainedWidth="true",其宽度将受到 ConstraintLayout 的水平约束限制。如果文本内容过长,它将被截断并显示省略号。

  • 使用 layout_constrainedWidth时可能需要注意的事项或常见问题

当使用 layout_constrainedWidth时,应确保控件的其他相关约束(如开始、结束、顶部和底部的约束)已正确设置,否则可能无法达到预期的效果。如果控件的内容可能非常长,并且你希望它能够在截断时显示省略号,那么还需要设置 android:ellipsize="end" 和 android:maxLines="1"(或其他适当的行数)。
在某些情况下,如果控件的高度也受到约束,并且你希望保持宽高比,可能需要同时使用 layout_constrainedHeight 属性。

layout_constrainedHeight使用情况类似layout_constrainedWidth。

MATCH_CONSTRAINT

当尺寸被设置成MATCH_CONSTRAINT时,结果尺寸默认会获得所有的尺寸大小。有几个其他修饰属性可以设置:

  • layout_constraintWidth_min 和layout_constraintHeight_min : 设置最小尺寸

  • layout_constraintWidth_max 和layout_constraintHeight_max : 设置最大尺寸

  • layout_constraintWidth_percent 和layout_constraintHeight_percent : 设置相对于父布局尺寸的的百分比

Min和Max

这些值可以用dp设置,也可以用"wrap", 与WRAP_CONTENT设置相同。

百分比尺寸

若要使用百分比,需要有如下设置:

  • 尺寸需要设置成MATCH_CONSTRAINT (0dp)
  • 默认应该设置百分比 app:layout_constraintWidth_default="percent" 或者app:layout_constraintHeight_default="percent"
  • 属性设置layout_constraintWidth_percent 或layout_constraintHeight_percent 数值范围为0 到1

比率

可以定义一个尺寸相对于另一个尺寸的比率,应用比率需要设置至少一个尺寸的值为0dp (或MATCH_CONSTRAINT), 同时需要设置属性layout_constraintDimensionRatio的比率数值。例如:

          <Button android:layout_width="wrap_content"android:layout_height="0dp"app:layout_constraintDimensionRatio="1:1" />

上述代码意思是,宽高比率为1:1。

比率值可以表达的意思有两种

  • float数值, 代表宽 / 高比率数值

  • 比例数值,代表"宽 : 高"

如果两个尺寸都设置为MATCH_CONSTRAINT (0dp). 在这种情况下,系统会设置最大的尺寸来满足所有约束和指定的比率。若要在一个尺寸的基础上指定另一个尺寸,需要用“ W," 或 “ H”,分别限定宽和高。例如,若一个尺寸被两个约束(宽为0dp且居中)设定,那么要约束另一个尺寸需要在比率前面添加字母W (约束宽度)或 H (约束高度),例如:

          <Button android:layout_width="0dp"android:layout_height="0dp"app:layout_constraintDimensionRatio="H,16:9"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintTop_toTopOf="parent"/>

上述代码的意思是,按钮的宽高比为16:9,宽度为父布局宽度。

7. 链式布局

链条是一组控件在单个轴(水平或垂直)上的布局。另一个轴的约束是独立的。

创建链条

一组控件被当作链条是因为控件之间通过双向链接在一起。

链条头

链条布局被第一个元素的属性控制。

链条头是水平链条的最左边控件,或垂直链条的最上边控件。

链条边距

链条连接中边距如果被指定了,它们将被考虑在内。在分散链条时,边距将在分配空间时被计算在内。

链条风格

当在链条的第一个元素上设置属性layout_constraintHorizontal_chainStyle 或layout_constraintVertical_chainStyle时,链条将会按照指定的风格(默认风格CHAIN_SPREAD)改变.

  • CHAIN_SPREAD -- 元素将要被分散 (默认风格)

  • 权重链 -- 在 CHAIN_SPREAD 模式中,如果一些控件被指定为MATCH_CONSTRAINT, 它们将分割可获得的空间。

  • CHAIN_SPREAD_INSIDE -- 类似, 链条的结点不会被分散

  • CHAIN_PACKED -- 链条的元素被打包到一起。子控件的水平或垂直属性将会影响被打包元素的位置

权重链

链条默认分给元素相同的空间。如果一个或者更多控件用MATCH_CONSTRAINT, 它们将获得空的空间 (在它们中被相同的分割). 在元素用MATCH_CONSTRAINT后,属性layout_constraintHorizontal_weight 和layout_constraintVertical_weight 可以控制将如何分配空间。例如,如果一个链条包含两个元素用MATCH_CONSTRAINT, 第一个元素用权重数值为2 ,另一个为1,那么第一个元素占用空间是第二个的两倍。

边距

当在链条中用边距时,边距是累加的。例如,水平链条上,一个元素距离右边10dp,下一个元素距离左边5dp,那么结果边距是两个元素的和是15dp。

在计算剩余空间定位所有元素时,每个元素和它的所有边距都应该被考虑在内。剩余空间不包含边距。

8. 虚拟辅助控件

除了上述功能以外,也可以用辅助控件来帮助布局。当前有Guideline控件允许创建水平和垂直引导线去定位相对于ConstraintLayout 布局的位置.。控件通过引导线的约束来定位位置。Barrier 和Group也可以。

9. 优化器

通过app:layout_optimizationLevel使用优化器:

  • none : 不用优化器

  • standard : 默认. 只优化direct 和barrier 约束

  • direct : 优化direct 约束

  • barrier : 优化barrier 约束

  • chain : 优化chain 约束(实验性)

  • dimensions : 优化dimensions 测量(实验性),减少匹配约束元素的测量的数目

属性值是一个掩码mask值,可以设置多个优化项目,例如:app:layout_optimizationLevel="direct|barrier|chain"

推荐文章

ConstraintLayout  |  Android Developers

https://zhuanlan.zhihu.com/p/44666184

相关文章:

Android详解——ConstraintLayout约束布局

目录 一、ConstraintLayout概述 二、ConstraintLayout属性介绍 1. 相对位置 2. 边距 3. 中心和偏移位置 中心位置 偏移位置 4. 圆形位置 5. 可见性 6. 尺寸约束 最小尺寸 WRAP_CONTENT :强制约束 MATCH_CONSTRAINT Min和Max 百分比尺寸 比率 7. 链式布局 创建…...

docker简单命令

docker images 查看镜像文件 docker ps -a 查看容器文件 docker rm 0b2 删除容器文件&#xff0c;id取前三位即可 docker rmi e64 删除镜像文件&#xff08;先删容器才能删镜像&#xff09;&#xff0c;id取前三位即可 在包含Dockerfile文件的目录…...

【linux】shell(36)-文件操作

1. 文件创建 1.1 使用 touch 命令创建空文件 touch filename创建一个名为 filename 的空文件。如果文件已存在&#xff0c;touch 会更新该文件的时间戳。 示例&#xff1a; touch file1.txt1.2 使用重定向符创建文件 > filename使用 > 符号创建一个空文件。如果文件…...

c语言——数据结构【链表:单向链表】

上篇→快速掌握C语言——数据结构【创建顺序表】多文件编译-CSDN博客 一、链表 二、单向链表 2.1 概念 2.2 单向链表的组成 2.3 单向链表节点的结构体原型 //类型重定义,表示存放的数据类型 typedef int DataType;//定义节点的结构体类型 typedef struct node {union{int l…...

​Python 标识符是啥?​

Python 的标识符就是我们写代码时用来给变量、函数、类等取名字的东西。 你写的 my_variable 是个标识符&#xff0c; 定义的 add_numbers 函数名也是个标识符&#xff0c; 甚至你写的 Cat 类名&#xff0c;也是标识符。 一句话总结&#xff1a;标识符就是代码里给“东西”起…...

视频及JSON数据的导出并压缩

npm下载安装 jszip 和 file-saver 这两个库来实现文件的压缩和保存功能&#xff1a; npm install jszip npm install file-saver 导入依赖库&#xff1a; import JSZip from jszip; import { saveAs } from file-saver; 方法实现&#xff1a; batchDownload() {const zip…...

VScode使用教程(菜鸟版)

目录 1.VScode是什么&#xff1f; 2.VScode的下载和安装&#xff1f; 2.1下载和安装 下载路径&#xff1a; 安装流程&#xff1a; 一、点击【Download for Windows】 二、等一小会儿的下载&#xff0c;找到并双击你下载好的.exe文件&#xff0c;开始进入安装进程 三、点…...

【漏洞复现】Grafana 安全漏洞(CVE-2024-9264)

🏘️个人主页: 点燃银河尽头的篝火(●’◡’●) 如果文章有帮到你的话记得点赞👍+收藏💗支持一下哦 一、漏洞概述 1.1漏洞简介 漏洞名称:Grafana 安全漏洞 (CVE-2024-9264)漏洞编号:CVE-2024-9264 | CNNVD-202410-1891漏洞类型:命令注入、本地文件包含漏洞威胁等级:…...

Android AOSP 源码中批量替换“phone“为“tablet“的命令详解

我来帮你写一篇关于这条命令的分析博客。 Android 项目中批量替换"phone"为"tablet"的命令详解 前言 在 Android 开发中,有时我们需要批量修改资源文件中的某些文本内容。今天我们来分析一条结合了 grep 和 sed 的强大命令,该命令用于将项目中的 “ph…...

基于JavaWeb(SSM+MySQL)问卷调查管理系统设计与实现毕业论文

标题:基于 JavaWeb&#xff08;SSMMySQL&#xff09;问卷调查管理系统设计与实现 内容:1.摘要 摘要&#xff1a;本文介绍了一个基于 JavaWeb&#xff08;SSMMySQL&#xff09;的问卷调查管理系统的设计与实现。该系统旨在为用户提供一个高效、便捷的问卷调查工具&#xff0c;帮…...

域内用户枚举与密码喷洒与密码爆破

域控&#xff1a;192.168.72.163 攻击者&#xff1a;192.168.72.162 域&#xff1a;hacker.com 用户枚举 as-rep 回复状态判断域用户 用户存在且启用&#xff1a;KDC_ERR_PREAUTH_REQUIRED (需要额外的预认证) 用户存在但禁用&#xff1a;KDC_ERR_CLIENT_REVOKED NT Stat…...

DIY 集合求并集(union)运算的代码 ← Python

【算法分析】 已知 Python 提供了求并集运算的函数 union。代码示例如下; >>> s1{1,2,3} >>> s2{2,3,7,1,9} >>> s1.union(s2) {1, 2, 3, 7, 9} >>> 不过&#xff0c;知其然也要知其所以然。 本例自己 DIY 集合求并集&#xff08;union…...

Redis bitmaps 使用

应用场景&#xff1a; 记录id为 1 的用户&#xff0c;2024年12月签到情况&#xff0c;并统计&#xff1b; 记录 1号签到 zxys-redis:0>setbit 1:202412 1 1 记录 2号签到 zxys-redis:0>setbit 1:202412 2 1 记录 3号未签到 zxys-redis:0>setbit 1:202412 3 0 …...

vue深层数据响应的问题

vue版本为v2.16 数据是数组数据&#xff0c;且初始数据为空&#xff1b; 当接口返回的数据直接赋值到字段之后导致深层的子项数据无法被监听到&#xff1b; 数据结构如下&#xff1a; //数据结构//初始化数据 data:[] 接口返回数据 resData:[{id:"",name:"&quo…...

解决Nginx + Vue.js (ruoyi-vue) 单页应用(SPA) 404问题的指南

问题描述 在使用Vue.js构建的单页应用&#xff08;SPA&#xff09;中&#xff0c;特别是像ruoyi-vue这样的框架&#xff0c;如果启用了HTML5历史记录模式进行路由管理&#xff0c;那么用户直接访问子路径或刷新页面时可能会遇到404错误。这是因为当用户尝试访问一个非根路径时…...

项目计划表如何制作?使用甘特图制作项目计划表的步骤

在项目管理中&#xff0c;项目计划是项目的核心要素&#xff0c;它详细记录了项目任务详情、责任人、时间规划以及所需资源。 这份计划不仅为项目推进提供指引&#xff0c;更是控制范围蔓延、争取更多支持的有力工具。 然而&#xff0c;如同项目管理的其他环节一样&#xff0…...

Flutter-底部分享弹窗(showModalBottomSheet)

showModalBottomSheet 构造函数的样式 Future<T?> showModalBottomSheet<T>({required BuildContext context, // 上下文对象&#xff0c;通常是当前页面的上下文bool isScrollControlled false, // 控制底部弹窗的大小&#xff0c;如果为…...

初学stm32 --- 时钟配置

目录 stm32时钟系统 时钟源 &#xff08;1&#xff09; 2 个外部时钟源&#xff1a; &#xff08;2&#xff09;2 个内部时钟源&#xff1a; 锁相环 PLL PLLXTPRE&#xff1a; HSE 分频器作为 PLL 输入 (HSE divider for PLL entry) PLLSRC&#xff1a; PLL 输入时钟源 (PL…...

LeetCode:226.翻转二叉树

跟着carl学算法&#xff0c;本系列博客仅做个人记录&#xff0c;建议大家都去看carl本人的博客&#xff0c;写的真的很好的&#xff01; 代码随想录 LeetCode&#xff1a;226.翻转二叉树 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 …...

(css)鼠标移入或点击改变背景图片

(css)鼠标移入或点击改变背景图片 html <div class"mapTip"><divv-for"(item, index) of legendList":key"index"class"mapTipOne":class"{ active: change index }"click"legendHandle(item, index)"…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应&#xff0c;这是一种非线性光学现象&#xff0c;主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场&#xff0c;对材料产生非线性响应&#xff0c;可能…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

3.3.1_1 检错编码(奇偶校验码)

从这节课开始&#xff0c;我们会探讨数据链路层的差错控制功能&#xff0c;差错控制功能的主要目标是要发现并且解决一个帧内部的位错误&#xff0c;我们需要使用特殊的编码技术去发现帧内部的位错误&#xff0c;当我们发现位错误之后&#xff0c;通常来说有两种解决方案。第一…...

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯&#xff0c;要想要能够将所有的电脑解锁&#x…...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

聊一聊接口测试的意义有哪些?

目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开&#xff0c;首…...

C++.OpenGL (14/64)多光源(Multiple Lights)

多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...

spring Security对RBAC及其ABAC的支持使用

RBAC (基于角色的访问控制) RBAC (Role-Based Access Control) 是 Spring Security 中最常用的权限模型&#xff0c;它将权限分配给角色&#xff0c;再将角色分配给用户。 RBAC 核心实现 1. 数据库设计 users roles permissions ------- ------…...