若依(ruoyi-cloud)脚手架解读,一篇精通,包票上手~

视频教程传送门:

基于SpringCloud Alibaba技术栈,若依微服务版(RuoYi-Cloud)脚手架入门精解,保证上手那种~_哔哩哔哩_bilibili基于SpringCloud Alibaba技术栈,若依微服务版(RuoYi-Cloud)脚手架入门精解,保证上手那种~共计23条视频,包括:01.前期准备与教学目标、02.若依框架基本了解、03.若依框架源码下载等,UP主更多精彩视频,请关注UP账号。https://www.bilibili.com/video/BV14g4y1N7tD/

一、教学目标

1.1 前置知识点

  • Java WEB 知识体系

  • Spring、SpringMVC、SpringBoot 传统MVC框架体系

  • MyBatis 持久层框架体系

  • SpringCloud Alibaba 微服务落地方案

  • Maven、Git、Idea 常规开发工具

  • MySQL、Redis 常见关系/非关系型数据库

1.2 教学目标

  • 掌握陌生项目解读技巧

  • 掌握若依(RuoYi-Cloud)框架

  • 掌握SpringCloud Alibaba体系项目开发套路

二、框架介绍

2.1 简介

一直想做一款后台管理系统,看了很多优秀的开源项目但是发现没有合适的。于是利用空闲休息时间开始自己写了一套后台系统。如此有了若依。她可以用于所有的Web应用程序,如网站管理后台,网站会员中心,CMS,CRM,OA。所有前端后台代码封装过后十分精简易上手,出错概率低。同时支持移动客户端访问。系统会陆续更新一些实用功能。

性别男,若依是给女儿取的名字(寓意:你若不离不弃,我必生死相依)

若依是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。

2.2 内置功能

  • 用户管理:用户是系统操作者,该功能主要完成系统用户配置。

  • 部门管理:配置系统组织机构(公司、部门、小组),树结构展现支持数据权限。

  • 岗位管理:配置系统用户所属担任职务。

  • 菜单管理:配置系统菜单,操作权限,按钮权限标识等。

  • 角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。

  • 字典管理:对系统中经常使用的一些较为固定的数据进行维护。

  • 参数管理:对系统动态配置常用参数。

  • 通知公告:系统通知公告信息发布维护。

  • 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。

  • 登录日志:系统登录日志记录查询包含登录异常。

  • 在线用户:当前系统中活跃用户状态监控。

  • 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。

  • 代码生成:前后端代码的生成(java、html、xml、sql)支持CRUD下载 。

  • 系统接口:根据业务代码自动生成相关的api接口文档。

  • 服务监控:监视当前系统CPU、内存、磁盘、堆栈等相关信息。

  • 缓存监控:对系统的缓存查询,删除、清空等操作。

  • 在线构建器:拖动表单元素生成相应的HTML代码。

  • 连接池监视:监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈。

2.3 主要特性

  • 完全响应式布局(支持电脑、平板、手机等所有主流设备)

  • 强大的一键生成功能(包括控制器、模型、视图、菜单等)

  • 支持多数据源,简单配置即可实现切换。

  • 支持按钮及数据权限,可自定义部门数据权限。

  • 对常用js插件进行二次封装,使js代码变得简洁,更加易维护

  • 完善的XSS防范及脚本过滤,彻底杜绝XSS攻击

  • Maven多项目依赖,模块及插件分项目,尽量松耦合,方便模块升级、增减模块。

  • 国际化支持,服务端及客户端支持

  • 完善的日志记录体系简单注解即可实现

  • 支持服务监控,数据监控,缓存监控功能。

2.4 演示地址

登录若依系统

账号:admin 密码:admin123

2.5 分类

2.5.1 传统版

2.5.1.1 源码地址

RuoYi: 🎉 基于SpringBoot的权限管理系统 易读易懂、界面简洁美观。 核心技术采用Spring、MyBatis、Shiro没有任何其它重度依赖。直接运行即可用

2.5.1.2 在线文档

介绍 | RuoYi

2.5.1.3 技术选型

2.5.1.4 代码结构

com.ruoyi     
├── common            // 工具类
│       └── annotation                    // 自定义注解
│       └── config                        // 全局配置
│       └── constant                      // 通用常量
│       └── core                          // 核心控制
│       └── enums                         // 通用枚举
│       └── exception                     // 通用异常
│       └── json                          // JSON数据处理
│       └── utils                         // 通用类处理
│       └── xss                           // XSS过滤处理
├── framework         // 框架核心
│       └── aspectj                       // 注解实现
│       └── config                        // 系统配置
│       └── datasource                    // 数据权限
│       └── interceptor                   // 拦截器
│       └── manager                       // 异步处理
│       └── shiro                         // 权限控制
│       └── web                           // 前端控制
├── ruoyi-generator   // 代码生成(不用可移除)
├── ruoyi-quartz      // 定时任务(不用可移除)
├── ruoyi-system      // 系统代码
├── ruoyi-admin       // 后台服务
├── ruoyi-xxxxxx      // 其他模块

 

2.5.2 前后端分离版本

2.5.2.1 源码地址

RuoYi-Vue: 🎉 基于SpringBoot,Spring Security,JWT,Vue & Element 的前后端分离权限管理系统,同时提供了 Vue3 的版本

2.5.2.2 在线文档

介绍 | RuoYi

2.5.2.3 技术选型

2.5.2.4 代码结构

后端结构

com.ruoyi     
├── common            // 工具类
│       └── annotation                    // 自定义注解
│       └── config                        // 全局配置
│       └── constant                      // 通用常量
│       └── core                          // 核心控制
│       └── enums                         // 通用枚举
│       └── exception                     // 通用异常
│       └── filter                        // 过滤器处理
│       └── utils                         // 通用类处理
├── framework         // 框架核心
│       └── aspectj                       // 注解实现
│       └── config                        // 系统配置
│       └── datasource                    // 数据权限
│       └── interceptor                   // 拦截器
│       └── manager                       // 异步处理
│       └── security                      // 权限控制
│       └── web                           // 前端控制
├── ruoyi-generator   // 代码生成(可移除)
├── ruoyi-quartz      // 定时任务(可移除)
├── ruoyi-system      // 系统代码
├── ruoyi-admin       // 后台服务
├── ruoyi-xxxxxx      // 其他模块

 前端结构

├── build                      // 构建相关  
├── bin                        // 执行脚本
├── public                     // 公共文件
│   ├── favicon.ico            // favicon图标
│   └── index.html             // html模板
│   └── robots.txt             // 反爬虫
├── src                        // 源代码
│   ├── api                    // 所有请求
│   ├── assets                 // 主题 字体等静态资源
│   ├── components             // 全局公用组件
│   ├── directive              // 全局指令
│   ├── layout                 // 布局
│   ├── plugins                // 通用方法
│   ├── router                 // 路由
│   ├── store                  // 全局 store管理
│   ├── utils                  // 全局公用方法
│   ├── views                  // view
│   ├── App.vue                // 入口页面
│   ├── main.js                // 入口 加载组件 初始化等
│   ├── permission.js          // 权限管理
│   └── settings.js            // 系统配置
├── .editorconfig              // 编码格式
├── .env.development           // 开发环境配置
├── .env.production            // 生产环境配置
├── .env.staging               // 测试环境配置
├── .eslintignore              // 忽略语法检查
├── .eslintrc.js               // eslint 配置项
├── .gitignore                 // git 忽略项
├── babel.config.js            // babel.config.js
├── package.json               // package.json
└── vue.config.js              // vue.config.js

2.5.3 微服务版本

2.5.3.1 源码地址

RuoYi-Cloud: 🎉 基于Spring Boot、Spring Cloud & Alibaba的分布式微服务架构权限管理系统,同时提供了 Vue3 的版本

2.5.3.2 在线文档

介绍 | RuoYi

2.5.3.3 技术选型

2.5.3.4 代码结构

后端结构

com.ruoyi     
├── ruoyi-ui              // 前端框架 [80]
├── ruoyi-gateway         // 网关模块 [8080]
├── ruoyi-auth            // 认证中心 [9200]
├── ruoyi-api             // 接口模块
│       └── ruoyi-api-system                          // 系统接口
├── ruoyi-common          // 通用模块
│       └── ruoyi-common-core                         // 核心模块
│       └── ruoyi-common-datascope                    // 权限范围
│       └── ruoyi-common-datasource                   // 多数据源
│       └── ruoyi-common-log                          // 日志记录
│       └── ruoyi-common-redis                        // 缓存服务
│       └── ruoyi-common-seata                        // 分布式事务
│       └── ruoyi-common-security                     // 安全模块
│       └── ruoyi-common-swagger                      // 系统接口
├── ruoyi-modules         // 业务模块
│       └── ruoyi-system                              // 系统模块 [9201]
│       └── ruoyi-gen                                 // 代码生成 [9202]
│       └── ruoyi-job                                 // 定时任务 [9203]
│       └── ruoyi-file                                // 文件服务 [9300]
├── ruoyi-visual          // 图形化管理模块
│       └── ruoyi-visual-monitor                      // 监控中心 [9100]
├──pom.xml                // 公共依赖

 前端结构

├── build                      // 构建相关  
├── bin                        // 执行脚本
├── public                     // 公共文件
│   ├── favicon.ico            // favicon图标
│   └── index.html             // html模板
├── src                        // 源代码
│   ├── api                    // 所有请求
│   ├── assets                 // 主题 字体等静态资源
│   ├── components             // 全局公用组件
│   ├── directive              // 全局指令
│   ├── layout                 // 布局
│   ├── plugins                // 通用方法
│   ├── router                 // 路由
│   ├── store                  // 全局 store管理
│   ├── utils                  // 全局公用方法
│   ├── views                  // view
│   ├── App.vue                // 入口页面
│   ├── main.js                // 入口 加载组件 初始化等
│   ├── permission.js          // 权限管理
│   └── settings.js            // 系统配置
├── .editorconfig              // 编码格式
├── .env.development           // 开发环境配置
├── .env.production            // 生产环境配置
├── .env.staging               // 测试环境配置
├── .eslintignore              // 忽略语法检查
├── .eslintrc.js               // eslint 配置项
├── .gitignore                 // git 忽略项
├── babel.config.js            // babel.config.js
├── package.json               // package.json
└── vue.config.js              // vue.config.js

2.5.4 移动版

2.5.4.1 源码地址

RuoYi-App: 🎉 RuoYi APP 移动端框架,基于uniapp+uniui封装的一套基础模版,支持H5、APP、微信小程序、支付宝小程序等,实现了与RuoYi-Vue、RuoYi-Cloud后台完美对接。

2.5.4.2 在线文档

介绍 | RuoYi

2.5.4.3 技术选型

2.5.4.4 代码结构

├── api                        // 所有请求  
├── components                 // 全局公用组件
├── pages                      // 页面文件
├── plugins                    // 通用方法
├── store                      // 全局 store管理
├── utils                      // 公用方法
├── static                     // 公共文件
│   ├── favicon.ico            // favicon图标
│   └── index.html             // html模板
│   └── logo.png               // logo图片
├── uni_modules                // uniui组件
│   ├── uni-badge              // 数字角标
│   ├── .........              // ........
│   ├── .........              // ........
├── App.vue                    // 应用配置
├── config.js                  // 环境配置
├── main.js                    // Vue初始化入口文件
├── manifest.json              // 配置打包
├── pages.json                 // 配置页面路由
├── permission.js              // 权限拦截
├── uni.scss                   // 全局样式变量

 

三、源码下载

3.1 说明

本教程以若依微服版(RuoYi-Cloud)为解读蓝本,所有源码、文件、截图、演示均为该版本。

3.2 下载

国内:RuoYi-Cloud: 🎉 基于Spring Boot、Spring Cloud & Alibaba的分布式微服务架构权限管理系统,同时提供了 Vue3 的版本

国外:https://github.com/yangzongzhuan/RuoYi-Cloud

3.3 Idea克隆

 

 

四、项目上手技巧

4.1 标准开源项目

标准开源项目:指符合特定标准和规范的开源软件项目。这些标准和规范通常由开源社区、行业组织或相关标准制定机构定义和推广。标准开源项目的目的是提供一致的质量标准和最佳实践,以促进开源软件的可靠性、互操作性和可持续发展。

大白话:代码、文件、教程等各种配套都齐全的项目。

4.1.1 看README.md

标准开源项目,都是有一个README.md这种文档,这个文档是项目的简介,一般会用大白话方式讲清楚项目背景,项目技术点,项目具体使用等。

4.1.2 看演示项目

若依管理系统

好处:快速了解项目具体功能,能做啥,实现效果怎么样。

4.1.3 看文档

介绍 | RuoYi

好处:该有的都有了

一个问题:看文档,看哪些内容?

0>视频教程(如果有)

1>项目结构/架构(如果有)

2>技术选型

3>功能模块

4>项目部署

5>项目其他

4.2 非标准开源项目

非标准开源项目是指没有遵循特定标准或规范的开源软件项目。这些项目可能是由个人、小团队或组织开发,其开发方式和治理模式可能与传统的标准开源项目有所不同。

大白话:代码、文件、教程等各种配套都不齐全的项目。

4.2.1 看README.md

如果有,必须看。但一般情况,都是下面这种:啥都是没有

 

4.2.2 看Jar依赖

没有使用Maven/Gradle传统项目,比如Java SE/JavaWeb项目,Jar依赖一般放置在lib文件夹,优先找它

如果使用Maven/Gradle常规项目,找pom.xml文件或build.gradle

一个问题:看Jar依赖目的是啥?

1>大体把握项目技术栈

要求:结合技术栈,YY一下代码可能的结构,后续项目解读时有参照蓝本。

比如: ​ MyBatis---domain----mapper.java-----mapper.xml

Springboot----Spring----Springmvc----Controller----启动类

SpringCloud Alibaba-----8个基本组件

2>大体推测项目有哪些功能

要求:常见的功能jar有熟悉,不认识,可以搜。

比如:

<dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>${swagger.fox.version}</version>
</dependency>
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId>
</dependency>
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId>
</dependency>

 

4.2.3 看代码结构

没有文档的帮助,只能借助代码结构名称大体推测项目可能具有模块,拥有的功能。

4.2.4 YY联想

非开源项目最麻烦一个点就是文件不齐全,少文档,少sql数据库,甚至代码不完整。这时候想解读通这代码就需要很丰富的想象能力。

类似一拳超人中地表最强的男人:King !哥的厉害全靠你想象

 

 

这个得结合个人开发经验,项目经验,生活阅历,连蒙靠猜推测去补齐项目逻辑啦。

比如:

缺SQL:找Mapper.xml/domain实体补齐

缺Jar包:根据项目启动报错信息,缺哪个补哪个

缺配置文件:项目依赖用到哪些jar,结合常规配置,补齐配置

缺少各种环境:结合个人开发经验,尝试补齐。

4.3 若依初探

若依脚手架算是一个较为标准的开源项目了,那它阶段就按照标准项目方式解读即可。

4.3.1 标准开源项目

4.3.1.1 看README.md

--了解项目整体

4.3.1.2 看演示项目

--了解项目效果

地址:若依管理系统

账号密码:admin/admin123

 

 

4.3.1.3 看文档

--了解项目细节

地址:介绍 | RuoYi

4.3.2 架构设计图

从图中解析出RuoYi-Cloud 使用微服务技术栈

网关:Gateway

远程调用:Ribbon/Feign

注册中心:Nacos Discovery

熔断降级:Sentinel

配置中心:Nacos Config

链路追踪:Sleuth+ZipKin/SkyWalking (没有集成,需要自己加)

4.3.3 代码结构

com.ruoyi     
├── ruoyi-ui              // 前端框架 [80]
├── ruoyi-gateway         // 网关模块 [8080]
├── ruoyi-auth            // 认证中心 [9200]
├── ruoyi-api             // 接口模块
│       └── ruoyi-api-system                          // 系统接口
├── ruoyi-common          // 通用模块
│       └── ruoyi-common-core                         // 核心模块
│       └── ruoyi-common-datascope                    // 权限范围
│       └── ruoyi-common-datasource                   // 多数据源
│       └── ruoyi-common-log                          // 日志记录
│       └── ruoyi-common-redis                        // 缓存服务
│       └── ruoyi-common-seata                        // 分布式事务
│       └── ruoyi-common-security                     // 安全模块
│       └── ruoyi-common-swagger                      // 系统接口
├── ruoyi-modules         // 业务模块
│       └── ruoyi-system                              // 系统模块 [9201]
│       └── ruoyi-gen                                 // 代码生成 [9202]
│       └── ruoyi-job                                 // 定时任务 [9203]
│       └── ruoyi-file                                // 文件服务 [9300]
├── ruoyi-visual          // 图形化管理模块
│       └── ruoyi-visual-monitor                      // 监控中心 [9100]
├──pom.xml                // 公共依赖

 

 

五、环境准备

项目运行前提需要准备环境,如果项目提供文档,直接看文档操作即可,如果没有文档,就结合开发经验/项目经验来配置。一般来说,项目环境准备都按照下面几个步骤。

5.1 语言环境

项目运行离不开语言支持,若依(RuoYi-Cloud)后端为Java项目,需要java环境,前端为Vue项目,需要Node.js环境,运行若依前需要将这些环境安装成功。

5.1.1 Java环境

5.1.2 node.js环境

一个node.js环境,一个事npm 软件安装工具

 

5.2 数据库环境

若依(RuoYi-Cloud)目前使用的数据库暂时只有MySQL跟Redis,后续可以根据项目需要添加其他数据库,比如MongoDB,Elasticsearch等。

5.2.1 MySQL环境

5.2.2 Redis环境

 

5.3 组件环境

若依(RuoYi-Cloud)使用的是SpringCloud Alibaba体系微服务落地方法,那就得安装2个必须组件:Nacos跟Sentinel。

5.3.1 Nacos环境

若依(RuoYi-Cloud)使用Nacos做注册中心与配置中心,所以需要提前准备该环境。

下载路径:Releases · alibaba/nacos · GitHub

这里注意,若依(RuoYi-Cloud)要求是Nacos 2.x版本,不要下错

 

进入bin目录启动,执行startup.cmd命令,注意需要使用单例模式启动,否则闪退

使用cmd 命令,进入命令框,执行下面命令
startup.cmd -m standalone 

 

5.3.2 Sentinel环境

若依(RuoYi-Cloud)使用Sentinel熔断降级组件,那么项目启动前,需要提前准备好

下载地址:https://github.com/alibaba/Sentinel/releases

下载完之后是一个jar包:sentinel-dashboard-1.8.0.jar, 使用java 命令执行就行

java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.0.jar

 

5.3.3 Seata环境

若依(RuoYi-Cloud)支持Seata实现分布式事务,如果需要,项目启动前就应该提前准备好

下载地址:https://github.com/seata/seata/releases

进入bin目录启动,执行seata-server.bat命令  

seata-server.bat --add-opens=java.base/java.lang=ALL-UNNAMED

六、项目配置与启动

当上面环境全部准备好之后,接下来就是项目配置。需要将项目相关配置修改成当前相关环境。

6.1 后端配置

6.1.1 数据库

新建数据库:ry-cloud 存储常规数据

字符编码:utf8mb4

导入SQL:sql/ry_20230223.sql sql/quartz.sql(可选--需要定时任务操作必须导入)

 

 

新建数据库:ry-config 存储nacos配置数据

字符编码:utf8mb4

导入SQL:sql/ry_config_20220929.sql

6.1.2 Nacos配置

若依(RuoYi-Cloud) 配置中心的项目配置文件,持久化在ry-config.config_info 表中,项目启动需要将这些配置文件加载到配置中心,所以需要额外配置一下Nacos,以增加对mysql数据源的支持。

进入nacos-server-2.2.2/conf 目录找:application.properties

 

修改配置

 

# db mysql
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://localhost:3306/ry-config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user=数据库账号
db.password=数据库密码

 

6.1.3 项目配置文件

Nacos配置好之后,启动成功后访问:http://localhost:8848/nacos 账号/密码 nacos/nacos

修改下面画红线的服务配置文件

 

主要改动:

Redis 的ip,端口,密码

MySQL ip,端口,账号,密码,数据库等。

比如:

 

6.2 后端启动

打开项目,执行XxxxApplication的启动类(启动没有先后顺序)

  • RuoYiGatewayApplication (网关模块 必须)

  • RuoYiAuthApplication (认证模块 必须)

  • RuoYiSystemApplication (系统模块 必须)

  • RuoYiMonitorApplication (监控中心 可选)

  • RuoYiGenApplication (代码生成 可选)

  • RuoYiJobApplication (定时任务 可选)

  • RuoYFileApplication (文件服务 可选)

 

加粗的启动即可。

 

 

6.3 前端配置与启动

若依(RuoYi-Cloud) 项目前端跟后端是保存在同一个目录夹的。

先进入这个目录,然后使用前端编辑工具打开即可,这里使用Visual Studio Code 打开

 

进入vscode之后,打开项目README.md文件

 

 打开vscode 的终端,执行上面命令

 

6.4 访问

当后端,前端都启动成功之后,若依(RuoYi-Cloud) 项目就算运行成功啦。

访问地址:http://localhost/

 

 

七、模块解读

项目解读可以说分为2部分: 1>项目结构解读(静态解读) 2>业务模块解读(动态解读)

前面种种都属于项目结构范畴,解下来就是业务模块解读,这里选择鉴权,网关,代码生成器3个核心模块讲解若依(RuoYi-Cloud)脚手架的使用。

7.1 解读技巧

只要是Java Web项目,流程主干线永远不变: 发起请求---处理请求----响应请求

找一个业务逻辑相对简单的模块,围绕主线去追踪即可。根据以往的经验,请求到响应大体流程图如下:

把上面流程具体化之后就是:

  • 前端

    客户端如何发起请求(关注路径/方式/参数),一般使用浏览器的F12查看

  • 后端

    接口接收请求,处理请求,响应请求。(关注:单个服务操作/多服务协同操作),一般追踪请求流程。

简单流程:网关---过滤器---拦截器--微服务(请求处理)

复杂流程:网关---上游过滤器---上游拦截器--上游微服务(处理)-----下游过滤器---下游拦截器--下游微服务(处理)

7.2 请求闭环

这里结合上面主线,走一个完整的请求闭环,以获取登录验证码获取为例子。

7.2.1 前端

项目进入第一个页面是登录页面

 

 

 浏览器F12,查看到第一个接口:http://localhost/dev-api/code

localhost:前端项目启动默认访问ip, 为本地

端口:没有端口,默认端口为80

dev-api:若依框架约定的开发环境使用上下文,可以在.env.development中配置

 

code:请求路径

完整的:http://locallhost:80/dev-api/code 是由下面异步请求发起的

 

 

 

 

 

当前端发起请求后,就到后端接收请求处理,处理请求,与响应请求啦。

7.2.2 后端

前端发起请求,后端接收请求,那请求最先去到哪呢?

 看若依(RuoYi-Cloud)框架的架构图,请求最先进入的网关。当然也可以通过前端代理服务配置定位到请求会转发到网关服务。

当确认请求入口之后,只需快速定位ruoyi-gateway即可。

 

此时还存在一个问题,网关哪个类处理/code请求?

如果有WebFlux编程经验,大体能猜到RouterFunctionConfiguration类

@Configuration
public class RouterFunctionConfiguration
{@Autowiredprivate ValidateCodeHandler validateCodeHandler;@SuppressWarnings("rawtypes")@Beanpublic RouterFunction routerFunction(){return RouterFunctions.route(RequestPredicates.GET("/code").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)),validateCodeHandler);}
}

 

RouterFunction 是 Spring WebFlux 中定义路由的函数式编程方式。

在 Spring WebFlux 中,我们可以使用 RouterFunction 来定义路由规则,将请求映射到相应的处理器函数上。

上面代码意思是前端发过来/code由validateCodeHandler 来处理

@Component
public class ValidateCodeHandler implements HandlerFunction<ServerResponse>
{@Autowiredprivate ValidateCodeService validateCodeService;@Overridepublic Mono<ServerResponse> handle(ServerRequest serverRequest){AjaxResult ajax;try{//构建验证码,封装成AjaxResult对象ajax = validateCodeService.createCaptcha();}catch (CaptchaException | IOException e){return Mono.error(e);}return ServerResponse.status(HttpStatus.OK).body(BodyInserters.fromValue(ajax));}
}

@Override
public AjaxResult createCaptcha() throws IOException, CaptchaException
{AjaxResult ajax = AjaxResult.success();boolean captchaEnabled = captchaProperties.getEnabled();ajax.put("captchaEnabled", captchaEnabled);....ajax.put("uuid", uuid);ajax.put("img", Base64.encode(os.toByteArray()));return ajax;}

 最终将生成的验证码封装在AjaxResult 响应回客户端。

 那如果说没有Spring WebFlux经验怎么办?很简单,使用idea 搜/code 字符,然后借助ChatGPT猜测代码啥意思

 

 

到这,一个完整请求闭环就完成了,后续其他请求便是同理可得。

7.3 网关模块

网关为项目入口,若依(RuoYi-Cloud)项目入口结构可以简化为这样

 

在ruoyi-gateway网关微服务中配置了所有微服务路由映射

 

 

spring:cloud:gateway:discovery:locator:lowerCaseServiceId: trueenabled: trueroutes:# 认证中心- id: ruoyi-authuri: lb://ruoyi-authpredicates:- Path=/auth/**filters:# 验证码处理- CacheRequestFilter- ValidateCodeFilter- StripPrefix=1# 代码生成- id: ruoyi-genuri: lb://ruoyi-genpredicates:- Path=/code/**filters:- StripPrefix=1# 定时任务- id: ruoyi-joburi: lb://ruoyi-jobpredicates:- Path=/schedule/**filters:- StripPrefix=1# 系统模块- id: ruoyi-systemuri: lb://ruoyi-systempredicates:- Path=/system/**filters:- StripPrefix=1# 文件服务- id: ruoyi-fileuri: lb://ruoyi-filepredicates:- Path=/file/**filters:- StripPrefix=1

前端发起所有请都统一经过网关,再借由网关路由统一转发。

访问ruoyi-file微服务路径规则: http://localhost:80/dev-api/file/**

访问ruoyi-gen微服务路径规则: http://localhost:80/dev-api/code​​​​​​/**

访问ruoyi-job微服务路径规则: http://localhost:80/dev-api/schule/**

访问ruoyi-system微服务路径规则: http://localhost:80/dev-api/system/**

访问ruoyi-auth微服务路径规则: http://localhost:80/dev-api/auth/**

7.4 鉴权模块

若依(RuoYi-Cloud)鉴权模块涉及到这几个组件

 

若依(RuoYi-Cloud)框架登录鉴权有2种模式:

外部鉴权:客户端访问服务端(微服务),以JWT令牌为判断依据,有且合法放行,没有或不合法拒绝

内部鉴权:上游微服务访问下游微服务,以请求头标记:from-source=inner有无位依据,有放行,没有拒绝

7.4.1 外部鉴权

7.4.1.1 步骤1:JWT获取

登录页面点击登录发起:http://localhost/dev-api/auth/login 请求

 

请求中auth前缀为网关配置ry-auth服务路由映射

 

 

 借助网格路由,进入ry-auth微服务,TokenController请求处理类

@RestController
public class TokenController
{@PostMapping("login")public R<?> login(@RequestBody LoginBody form){// 用户登录LoginUser userInfo = sysLoginService.login(form.getUsername(), form.getPassword());// 获取登录tokenreturn R.ok(tokenService.createToken(userInfo));}
}    
    /*** 创建令牌*/public Map<String, Object> createToken(LoginUser loginUser){String token = IdUtils.fastUUID();Long userId = loginUser.getSysUser().getUserId();String userName = loginUser.getSysUser().getUserName();loginUser.setToken(token);loginUser.setUserid(userId);loginUser.setUsername(userName);loginUser.setIpaddr(IpUtils.getIpAddr());refreshToken(loginUser);  //redis缓存令牌// Jwt存储信息Map<String, Object> claimsMap = new HashMap<String, Object>();claimsMap.put(SecurityConstants.USER_KEY, token);claimsMap.put(SecurityConstants.DETAILS_USER_ID, userId);claimsMap.put(SecurityConstants.DETAILS_USERNAME, userName);// 接口返回信息Map<String, Object> rspMap = new HashMap<String, Object>();rspMap.put("access_token", JwtUtils.createToken(claimsMap));rspMap.put("expires_in", expireTime);return rspMap;}

响应返回:

7.4.1.2 步骤2:JWT鉴权

当客户登录成功之后,后续请求进入网关,网关转发到对应的微服务,该微服务会引用:ruoyi-common-security 鉴权模块,请求进来后,切面判断请求持有的JWT令牌,有且合法放行,没有或不合法拒绝

 

7.4.1.3 步骤3:JWT鉴权实现

@Aspect
@Component
public class PreAuthorizeAspect
{/*** 构建*/public PreAuthorizeAspect(){}/*** 定义AOP签名 (切入所有使用鉴权注解的方法)*/public static final String POINTCUT_SIGN = " @annotation(com.ruoyi.common.security.annotation.RequiresLogin) || "+ "@annotation(com.ruoyi.common.security.annotation.RequiresPermissions) || "+ "@annotation(com.ruoyi.common.security.annotation.RequiresRoles)";/*** 声明AOP签名*/@Pointcut(POINTCUT_SIGN)public void pointcut(){}/*** 环绕切入* * @param joinPoint 切面对象* @return 底层方法执行后的返回值* @throws Throwable 底层方法抛出的异常*/@Around("pointcut()")public Object around(ProceedingJoinPoint joinPoint) throws Throwable{// 注解鉴权MethodSignature signature = (MethodSignature) joinPoint.getSignature();checkMethodAnnotation(signature.getMethod());try{// 执行原有逻辑Object obj = joinPoint.proceed();return obj;}catch (Throwable e){throw e;}}/*** 对一个Method对象进行注解检查*/public void checkMethodAnnotation(Method method){// 校验 @RequiresLogin 注解RequiresLogin requiresLogin = method.getAnnotation(RequiresLogin.class);if (requiresLogin != null){AuthUtil.checkLogin();}// 校验 @RequiresRoles 注解RequiresRoles requiresRoles = method.getAnnotation(RequiresRoles.class);if (requiresRoles != null){AuthUtil.checkRole(requiresRoles);}// 校验 @RequiresPermissions 注解RequiresPermissions requiresPermissions = method.getAnnotation(RequiresPermissions.class);if (requiresPermissions != null){AuthUtil.checkPermi(requiresPermissions);}}
}

 阅读上面的切面代码,最终得出

只要接口方法只要贴有上面3个注解,都需要进行外部鉴权。比如:

/**
* 获取用户列表
*/
@RequiresPermissions("system:user:list")
@GetMapping("/list")
public TableDataInfo list(SysUser user)
{startPage();List<SysUser> list = userService.selectUserList(user);return getDataTable(list);
}

 

7.4.2 内部鉴权

内部鉴权是微服务与微服务间鉴权,发生在上游微服务访问下游微服务,以请求头标记:from-source=inner有无位依据,有放行,没有拒绝,其目的是实现网络隔离。

来自网关请求,以JWT进行鉴权,来自内部远程调用请求,以from-source=inner进行鉴权,其他非法请求直接拒绝。

还是以ry-auth微服务的TokenController类的登录方法为案例

7.4.2.1 步骤1:远程调用过程

登录请求,先到TokenController类login方法

@RestController
public class TokenController
{@Autowiredprivate TokenService tokenService;@Autowiredprivate SysLoginService sysLoginService;@PostMapping("login")public R<?> login(@RequestBody LoginBody form){// 用户登录LoginUser userInfo = sysLoginService.login(form.getUsername(), form.getPassword());// 获取登录tokenreturn R.ok(tokenService.createToken(userInfo));}
}

 login方法中用到:SysLoginService接口login逻辑

private SysLoginService sysLoginService;
sysLoginService.login(form.getUsername(), form.getPassword());

观察SysLoginService类,里面引用了接口:RemoteUserService

@Component
public class SysLoginService
{@Autowiredprivate RemoteUserService remoteUserService;/*** 登录*/public LoginUser login(String username, String password){......// 查询用户信息R<LoginUser> userResult = remoteUserService.getUserInfo(username, SecurityConstants.INNER);......}
}

观察RemoteUserService接口所在位置,明显与TokenController/SysLoginService不在同一微服务。

RemoteUserService 属于ry-system微服务,而TokenController类属于ry-auth微服务,那么此处的remoteUserService.getUserInfo为远程调用。

一个问题:既然为远程调用,跟普通接口调用有啥区别?

定义区别:

使用feign组件,定义远程接口

@FeignClient(contextId = "remoteUserService", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteUserFallbackFactory.class)
public interface RemoteUserService
{/*** 通过用户名查询用户信息** @param username 用户名* @param source 请求来源* @return 结果*/@GetMapping("/user/info/{username}")public R<LoginUser> getUserInfo(@PathVariable("username") String username, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);}

 接口定义,除了正常的username参数之外,多了一个请求头

@RequestHeader(SecurityConstants.FROM_SOURCE) String source

调用区别:

使用Feign组件发起远程接口调用,需要多传一个SecurityConstants.INNER 参数

remoteUserService.getUserInfo(username, SecurityConstants.INNER);

 

这是为何?

SecurityConstants.INNER为内部微服务间远程调用请求头标识,上游微服务调用时,添加该标识的请求头,下游微服务接收请求前,进行请求头校验。

即:

定义是指定请求头key:SecurityConstants.FROM_SOURCE

getUserInfo(@PathVariable("username") String username,@RequestHeader(SecurityConstants.FROM_SOURCE) String source);

调用时,指定请求头value:SecurityConstants.INNER

remoteUserService.getUserInfo(username, SecurityConstants.INNER);

最终合并

SecurityConstants.FROM_SOURCE = SecurityConstants.INNER

from-source = inner

7.4.2.2 步骤2:远程正式调用

上面定义的远程接口,最终通过feign方式调用到ruoyi-system微服务SysUserController类的info接口

SysUserController类的info接口

 

@RestController
@RequestMapping("/user")
public class SysUserController extends BaseController
{    /*** 获取当前用户信息*/@InnerAuth@GetMapping("/info/{username}")public R<LoginUser> info(@PathVariable("username") String username){SysUser sysUser = userService.selectUserByUserName(username);if (StringUtils.isNull(sysUser)){return R.fail("用户名或密码错误");}// 角色集合Set<String> roles = permissionService.getRolePermission(sysUser);// 权限集合Set<String> permissions = permissionService.getMenuPermission(sysUser);LoginUser sysUserVo = new LoginUser();sysUserVo.setSysUser(sysUser);sysUserVo.setRoles(roles);sysUserVo.setPermissions(permissions);return R.ok(sysUserVo);}
}    

这里留意,info方法上面有个@InnerAuth 注解,表示当前info方法为远程调用方法,需要进行远程校验,也即:内部鉴权。

7.4.2.3 步骤3:内部鉴权

@Aspect
@Component
public class InnerAuthAspect implements Ordered
{@Around("@annotation(innerAuth)")public Object innerAround(ProceedingJoinPoint point, InnerAuth innerAuth) throws Throwable{String source = ServletUtils.getRequest().getHeader(SecurityConstants.FROM_SOURCE);// 内部请求验证if (!StringUtils.equals(SecurityConstants.INNER, source)){throw new InnerAuthException("没有内部访问权限,不允许访问");}String userid = ServletUtils.getRequest().getHeader(SecurityConstants.DETAILS_USER_ID);String username = ServletUtils.getRequest().getHeader(SecurityConstants.DETAILS_USERNAME);// 用户信息验证if (innerAuth.isUser() && (StringUtils.isEmpty(userid) || StringUtils.isEmpty(username))){throw new InnerAuthException("没有设置用户信息,不允许访问 ");}return point.proceed();}/*** 确保在权限认证aop执行前执行*/@Overridepublic int getOrder(){return Ordered.HIGHEST_PRECEDENCE + 1;}
}

阅读上面的切面代码,发起切面是切入点事贴有@InnerAuth接口方法。

7.5 代码生成模块

若依(RuoYi-Cloud)代码生成模块是一个简单模块,功能顾名思义,用于构建若依体系的代码。

 

启动后,访问页面:

 

这里演示一下代码生成器使用过程。

7.5.1 步骤1:创建表

在ry-cloud库中创建一个Employee表

CREATE TABLE `sys_employee` (`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',`name` varchar(255) DEFAULT NULL COMMENT '名称',`age` int DEFAULT NULL COMMENT '年龄',PRIMARY KEY (`id`)
) ENGINE=InnoDB  COMMENT='员工表';

 

7.5.2 步骤2:导入新建表

在代码生成界面导入新建表

 

7.5.3 步骤3:定制代码信息

7.5.3.1 基本信息

 

 

7.5.3.2 字段信息

 

字段列名:表中列的名称

字段描述:生成实体类属性注释

物理类型:表中列的类型

Java类型:生成实体类属性变量类型

Java属性:生成实体类属性名

插入:定义添加操作模态框表单控件,选中表示模态框有这个输入空间

编辑:定义编辑操作模态框表单控件,选中表示模态框有这个输入空间

列表:表中数据在列表时,该列数据是否显示,选中为要显示

查询:该列是否作为列表的查询条件,选中为需要作为查询条件

查询方式:作为查询条件时,使用匹配方式

显示类型:查询条件输入类型

字典类型:查询条件显示类型如果是下拉框,使用字典类型,实现下拉选择

 

 

7.5.3.3 生成信息

 

生成模板:一般不动,以单表操作为主

生成包路径:指定当前代码生成根包路径

生成模块名:该功能所属模块,落地到代码就是所在微服务名称,ruoyi-gateway配置的路由映射路径名

生成业务名:该功能英文名,落地到代码就是controller中操作资源名, 比如:/employee

生成功能名:该功能中文名称

上级菜单:该功能页面展示菜单连接挂载在哪个上级菜单。

7.5.3.4 预览

配置上面各种信息成功之后,可以点击预览,根据需要微调

 

 

7.5.3.5 生成代码

确定无误之后,直接点生成代码

 

7.5.4 步骤4:使用代码

压缩包解压得到几个文件:

 

7.5.4.1 employeeMenu.sql

涉及要添加的菜单,菜单权限,在navicat中执行即可。

-- 菜单 SQL
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('员工', '1', '1', 'employee', 'system/employee/index', 1, 0, 'C', '0', '0', 'system:employee:list', '#', 'admin', sysdate(), '', null, '员工菜单');-- 按钮父菜单ID
SELECT @parentId := LAST_INSERT_ID();-- 按钮 SQL
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('员工查询', @parentId, '1',  '#', '', 1, 0, 'F', '0', '0', 'system:employee:query',        '#', 'admin', sysdate(), '', null, '');insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('员工新增', @parentId, '2',  '#', '', 1, 0, 'F', '0', '0', 'system:employee:add',          '#', 'admin', sysdate(), '', null, '');insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('员工修改', @parentId, '3',  '#', '', 1, 0, 'F', '0', '0', 'system:employee:edit',         '#', 'admin', sysdate(), '', null, '');insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('员工删除', @parentId, '4',  '#', '', 1, 0, 'F', '0', '0', 'system:employee:remove',       '#', 'admin', sysdate(), '', null, '');insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('员工导出', @parentId, '5',  '#', '', 1, 0, 'F', '0', '0', 'system:employee:export',       '#', 'admin', sysdate(), '', null, '');

 执行成功后,刷新前端项目,可以看到菜单

7.5.4.2 vue

ruoyi-ui前端employee这个模块设计到vue页面,与js

 

分别拷贝到项目api目录,跟views目录  

刷新之后,点击员工菜单,缺少后端接口

 

7.5.4.3 main

后端接口代码,将main代码拷贝到ruoyi-system main目录中即可

 

然后,重启ruoyi-system服务,再访问。

 

八、定制微服务

8.1 需求

定制微服务-ruoyi-modules-test

8.2 代码结构

对外api:ruoyi-api-test

微服务:ruoyi-modules-test

8.3 实现步骤

8.3.1 步骤1:定义ruoyi-api-test

 

导入依赖参考ruoyi-api-system

创建包结构参考ruoyi-api-system

 

这里注意包命名规则:

com.ruoyi-----公司域名倒写

system------微服务名

api------模块名

8.3.2 步骤2:等级ruoyi-api-test依赖

去父项目ruoyi pom.xml文件中登记新建的api

<!-- test接口 -->
<dependency><groupId>com.ruoyi</groupId><artifactId>ruoyi-api-test</artifactId><version>${ruoyi.version}</version>
</dependency>

 

8.3.3 步骤3:定义ruoyi-modules-test

导入依赖参考,ruoyi-system 注意要导入ruoyi-api-test依赖

创建包结构参考ruoyi-system

 

8.3.4 步骤4:定制微服务配置文件

 

nacos克隆一份配置文件--克隆自ruoyi-system-dev.yml

 

 

8.3.5 步骤5:定制网关微服务路由

 

到这,定制微服务就结束了,剩下操作就是常规crud了。

九、小结

将整篇教程总结一下:若依(Ruoyi-Cloud)版本使用

启动

1>官网克隆项目到idea

2>按照文档,建库,建表,配置nacos

3>准备各种环境,修改本地配置

4>前后端启动,测试。

模块解读

1>网关模块,所有请求入口

2>鉴权模块,外部鉴权,内部鉴权

3>代码生成模块,先建表,再定制,后覆盖

微服务定制

1>拷贝模仿现有api/modules

2>配置中心加配置文件

3>网关配置转发路由

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/31978.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

chatgpt赋能python:Python主菜单:让你的网站更加用户友好

Python主菜单&#xff1a;让你的网站更加用户友好 如果你是一个使用Python编程语言的网站开发者&#xff0c;那么你肯定需要一个主菜单来引导你的用户。一个好的主菜单可以让你的网站更加用户友好&#xff0c;方便用户快速找到需要的内容。而怎样设计一个优秀的主菜单呢&#…

PrimeVue - 全面升级!免费开源、优雅好用的 Vue3 UI 组件库,可选主题超多

新版本发布了&#xff0c;主题超好看&#xff0c;还有很多独有的组件&#xff0c;强烈推荐给大家。 关于新版本 PrimeVue PrimeVue 是一个用于 Vue.js 3.x 开发的 web UI 组件库。早在2021年10月我就推荐过这个组件库&#xff0c;至今一年多的时间&#xff0c;开发迭代非常快…

安卓APP源码和设计报告——健身系统

一、设计背景 1.需求分析 对于很多人来说拥有一副好身材能让自己增添不少魅力;对于爱吃而又担心自己发胖的人来说适当的运动健身是最好的选择。移动互联网时代&#xff0c;市场上“约跑”“约健身”健身APP软件成为新时代闺蜜朋友的互动模式&#xff0c;健身热潮的来临&#xf…

求和!李姐万岁!用ChatGPT写GitBook布局锤子便签配色的WordPress主题

我早期在Github写《Chrome插件英雄榜》连载的时候&#xff0c;用的是GitBook的自动构建功能&#xff0c;也就是在Github仓库&#xff0c;按照一定的规范存储markdown格式文章和配置文件&#xff0c;GitBook就会自动构建一本书&#xff0c;供读者阅读。 GitBook阅读体验确实不错…

ChatGPT + X = 更多可能性

ChatGPT具有多种先进性特征&#xff0c;一经发布备受瞩目&#xff0c;作为一个由OpenAI训练的大型自然语言处理模型&#xff0c;可实现自然语言生成、语言翻译、自然语言理解、语言摘要等一系列功能。发布两个月后月活用户突破1亿&#xff0c;成为史上用户增长速度最快的消费级…

敏捷教练是做什么的?

如果想知道敏捷教练是做什么的&#xff0c;看招聘要求就明白了&#xff1a; https://www.zhipin.com/job_detail/1416132495.html 职位描述 岗位职责&#xff1a; 1. 作为敏捷教练&#xff0c;研究、引入、推广业界先进的研发管理思想、方法论与实践。 2. 指导与推动部门的精…

图解敏捷教练和 ScrumMaster

[运营专题]零预算引爆个人和企业品牌【原文链接】 Selenium 自动化测试从零实战【原文链接】 原来这样做&#xff0c;才能向架构师靠近【原文链接】 Cordova App 打包全揭秘【原文链接】 TensorFlow on Android&#xff1a;物体识别【原文链接】 TensorFlow on Android&am…

AI解码意念!类ChatGPT模型高准确率(82%)解码大脑思想

一段视频展示了一种新的语言解码过程的程式化描述。解码器生成多个单词序列(纸条)&#xff0c;并通过将用户大脑反应的预测与实际记录的反应进行比较&#xff0c;预测每个候选单词序列与实际单词序列的相似程度。Credit: Jerry Tang/Alexander Huth 像ChatGPT这样的人工智能程序…

gpt4和chatGPT的区别

一觉醒来&#xff0c;万众期待的GPT-4&#xff0c;它来了&#xff01; OpenAI老板Sam Altman直接开门见山地介绍说&#xff1a; 这是我们迄今为止功能最强大的模型&#xff01; 有多强&#xff1f; 根据OpenAI官方的介绍&#xff0c;GPT-4是一个超大的多模态模型&#xff0c;也…

[新人自制/Med-VQA] 这是一个可以帮忙看“片子“的 AI-Demo,欢迎大神来访留言

开局先向 coolwulf 大神致敬&#xff01; Demo 地址 介绍博客 和近期大火的 ChatGPT 那种生成式不同&#xff0c;这个模型是个分类模型&#xff0c; 在自然问答的情况下还是很蠢的&#xff0c;但也希望在医学领域能够帮助到真的有需要的人。 后续也会根据反馈不断验证模型性…

2023最新软件测试面试题汇总,一天拿到3个offer就靠他

目录 软件工程 Linux 数据库 sql语句 测试概念和模型 测试计划与工具 测试用例设计 Web端自动化 白盒测试 shell脚本 接口测试 性能测试 移动端自动化 总结 重点&#xff1a;配套学习资料和视频教学 软件工程 1. 阐述软件生命周期都有哪些阶段&#xff1f;常见…

手撕Boost!Boost公式推导及实验验证

文章在微信公众号“硬件工程师炼成之路”首发&#xff0c;敬请关注。 前一段时间写了一下Buck电路的振铃&#xff0c;不少同学给我留了作业&#xff0c;让我说说Boost。今天就来看看Boost电路。 友情提示&#xff1a;本文字数1W了&#xff0c;有点长&#xff0c;请点赞收藏加关…

一个简单三层神经网络BP算法的公式推导

一个简单的三层神经网络BP算法的公式推导 神经网络表示梯度下降法前向误差传播反向误差传播 神经网络表示 让我们来看一个最简单的神经网络&#xff0c;该神经网络只有三层&#xff0c;分别是输入层&#xff0c;隐藏层和输出层。 为了表示方便&#xff0c;我们把线性函数和非…

BP神经网络和CNN公式推导

CNN理论基础 CNN基本结构 图一 CNN基本结构 CNN卷积神经网络的构成&#xff0c;主要由输入层&#xff0c;卷积层&#xff0c;池化层&#xff0c;全连接层&#xff0c;输出层等。 &#xff08;1&#xff09;输入层&#xff1a;计算机将输入层理解为若干矩阵。在数据输入前&am…

计算机视觉 | 面试题:12、手动推导反向传播公式BP

问题 现在才意识到,卷积神经网络在不同的层上的反向传播的计算公式不一样,之前一直按照全连接层的那种简单反向传播去理解了。 全连接层反向传播 在数据表示上,将全连接神经网络的每一层神经元都表示为一个列向量。每一层的神经元,会将上一层神经元的输出作为输入,通过乘…

Bp算法公式推导推导-详解

前言 学习深度学习我们应该从Bp开始,一下是学习路径 如果我们把深度学习比喻一棵大树,Bp相当于根,LeNet相当于茎,GAN,RNN,CNN相当于树叶. Bp 神经网络的简单理解 bp是 Back Propagation 的简写 &#xff0c;意思是反向传播。而神经网络&#xff0c;听着高大上&#xff0c;其实…

人工神经网络推理机制,bp神经网络公式推导

Recurrent network 的backpropagation公式 怎么样推导出来 反向传播算法&#xff08;Backpropagation&#xff09;是目前用来训练人工神经网络&#xff08;ArtificialNeuralNetwork&#xff0c;ANN&#xff09;的最常用且最有效的算法。 其主要思想是&#xff1a;&#xff08…

BP神经网络理解及公式推导

BP神经网络理解及公式推导 __508任务 仅个人学习记录使用&#xff0c;可能有误 一、人工神经网络 人工神经网络&#xff08;ANN&#xff09;是一种旨在模仿人脑结构及其功能的由多个非常简单的处理单元彼此按某种方式相互连接而形成的计算机系统&#xff0c;该系统靠其状态对…

特斯拉面试,工控经典PLC题目:一键启动功能实现解法分析,少个坑,给自己多个机会

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、问题分析&#xff1a;二、模拟运行三、还有没有更简单的 前言 PLC 面试经典题目&#xff0c;一键启动功能&#xff1a;单个按钮按下一次控制灯亮起&#x…