spring-cloud微服务gateway

核心部分:routes(路由), predicates(断言),filters(过滤器)

pom依赖

 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>

yml配置网关

server:port: 8087
spring:application:name: gateway-nacoscloud:gateway:routes: #路由数组[路由 就是指定当请求满足什么条件的时候转到哪个微服务]- id: product_route  #当前路由的标识,要求唯-uri: http://localhost:8086 #请求要转发到的地址order: 1 #路由的优先级,数字越小级别越高predicates: #断言(就是路由转发要满足的条件)- Path=/product-service/** #当请求路径满足Path指定的规则时,才进行路由转发#http://localhost:8087/product-service/product/9  路由器到⬇#http://localhost:8086/product-service/product/9filters: #过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改- StripPrefix=1 #转发之前去掉1层路径##http://localhost:8086/product/9

yml注册到nacos配置网关

server:port: 8087
spring:application:name: gateway-nacoscloud:nacos:discovery:server-addr: 192.168.11.47:18848username: nacospassword: nacosgateway:routes: #路由数组[路由 就是指定当请求满足什么条件的时候转到哪个微服务]- id: product_route  #当前路由的标识,要求唯-uri: lb://product_naocs #lb指的是从nacos中按名称获取微服务,并遵循负载均衡策略order: 1 #路由的优先级,数字越小级别越高predicates: #断言(就是路由转发要满足的条件)- Path=/product-service/** #当请求路径满足Path指定的规则时,才进行路由转发filters: #过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改- StripPrefix=1 #转发之前去掉1层路径,

yml配置网关(约定大于配置的方式,一般不用这样的配置),例如访问http://localhost:8087/product-service/product/9 ,中的product-service为服务的名字

server:port: 8087
spring:application:name: gateway-nacoscloud:nacos:discovery:server-addr: 192.168.11.47:18848username: nacospassword: nacosgateway:discovery:locator:enabled: true    #是否启动自动识别nacos服务(约定大于配置)

注意:若要使用自定义配置,则“不能开启注册中心的路由功能”,否则自定义的策略会失,设置中心路由功能为false

server:port: 8087
spring:application:name: gateway-nacoscloud:nacos:discovery:server-addr: 192.168.11.47:18848username: nacospassword: nacosgateway:discovery:locator:enabled: false  #是否启动自动识别nacos服务(约定大于配置)

查看网关内置断言官网文档,如果用上时间可以设置获取使用方法:ZonedDateTime.now(),获取

内置断言例子,日期2024-01-20T17:42:47都可以访问,超过时间访问返回404

server:port: 8087
spring:application:name: gateway-nacoscloud:nacos:discovery:server-addr: 192.168.11.47:18848username: nacospassword: nacosgateway:routes: #路由数组[路由 就是指定当请求满足什么条件的时候转到哪个微服务]- id: product_route #当前路由的标识,要求唯-uri: http://localhost:8086 #请求要转发到的地址order: 1 #路由的优先级,数字越小级别越高predicates: #断言(就是路由转发要满足的条件)- Path=/product-service/** #当请求路径满足Path指定的规则时,才进行路由转发- Before=2024-08-20T17:42:47.789-07:00[America/Denver]filters: #过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改- StripPrefix=1 #转发之前去掉1层路径,- id: stock-nacos #当前路由的标识,要求唯-uri: http://localhost:8085 #请求要转发到的地址order: 1 #路由的优先级,数字越小级别越高predicates: #断言(就是路由转发要满足的条件)- Path=/stock-nacos/** #当请求路径满足Path指定的规则时,才进行路由转发- Before=2024-08-20T17:42:47.789-07:00[America/Denver]filters: #过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改- StripPrefix=1 #转发之前去掉1层路径,

内部断言的类名是有断言前缀和后缀组成如下

Path+RoutePredicateFactory
RemoteAddr+RoutePredicateFactory
RemoteAddr+RoutePredicateFactory
Header+RoutePredicateFactory

  • 基于远程地址的断言工厂

  • RemoteAddrRoutePredicateFactory:接收一个IP地址段,判断请求主机地址是否在地址段中
- RemoteAddr=192.168.1.1/24
  • 基于Cookie的断言工厂

  • CookieRoutePredicateFactory:接收两个参数,cookie 名字和一个正则表达式。 判断请求cookie是否具有给定名称且值与正则表达式匹配。
- RemoteAddr=chocolate, ch.
  • 基于Header的断言工厂

  • HeaderRoutePredicateFactory:接收两个参数,标题名称和正则表达式,判断请求Header是否具有给定名称且值与正则表达式匹配。
- Header=X-Request-Id,\d+
  • 基于Host的断言工

  • HostRoutePredicateFactory:接收一个参数,主机名模式。判断请求的Host是否满足匹配规则
- Host=**.testhost.org
基于Method请求方法的
  • 基于Method请求方法的断言工厂

  • MethodRoutePredicateFactory:接收一个参数,判断请求类型是否跟指定的类型匹配
 - Method=GET
  1. 基于Path请求路径的断言工厂

  2. PathRoutePredicateFactory:接收一个参数,判断请求的URI部分是否满足路径规则。
#多个路径使用逗号,隔开
- Path=/foo/{segment}1 , /product/add
  • 基于Query请求参数的断言工厂

  • QueryRoutePredicateFactory:接收两个参数,请求param和正则表达式,判断请求参数是否具有给定名称且值与正则表达式匹配,
- Query=baz, ba.

基于Path请求路径的断言工厂

自定义路由断言工厂

可以查看路径路由的断言工厂,选择AbstractRoutePredicateFactory按Ctrl+H既可以显示出全部的路由断言工厂,可以复制一份修改成自定义的断言工厂

在这里插入图片描述

自定义路由断言工厂需要继承 AbstadRoutepredicatefacdoy类,重写 ap)y方法的透辑,在apy方法中可以通过 excthange.geiequest) 拿到 serneiHpReque 对象,从而可以获取到清求的参数、请求方式、请求头等信息

1. 必须spring组件 bean
2. 类必须加上RoutePredicateFactory作为结尾(底层的处理的约定大于配置自定会读取到的)
3. 必须继承AbstractRoutePredicateFactory
4. 必须声明静态内部类 声明属性来接收 配置文件中对应的断言的信息
5. 需要结合shortcutFieldOrder进行绑定
6. 通过apply进行逻辑判断 true就是匹配成功 false匹配失败

自定义路由断言工厂类

package com.test.gate.config;import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.cloud.gateway.handler.predicate.GatewayPredicate;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.server.ServerWebExchange;import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;/*** @Description:* @Author: xu* @Data: 2024-2024/4/11-21* @Version: V1.0*/
@Component
public class CheckAuthRoutePredicateFactory extends AbstractRoutePredicateFactory<CheckAuthRoutePredicateFactory.Config> {public CheckAuthRoutePredicateFactory() {super(Config.class);}public List<String> shortcutFieldOrder() {return Arrays.asList("param");}public Predicate<ServerWebExchange> apply(final Config config) {return new GatewayPredicate() {public boolean test(ServerWebExchange exchange) {if (config.getParam().equals("zhangSan")) {return true;}return false;}public Object getConfig() {return config;}public String toString() {return String.format("Query: param=%s regexp=%s", config.getParam());}};}@Validatedpublic static class Config {private String param;public Config() {}public String getParam() {return this.param;}public void setParam(String param) {this.param = param;}}
}

yml配置(如果一个路由里面有多个断言条件是且的关系,都需要满足才跳转uri)

server:port: 8087
spring:application:name: gateway-nacoscloud:nacos:discovery:server-addr: 192.168.11.47:18848username: nacospassword: nacosgateway:
#      discovery:
#        locator:
#          enabled: true    #是否启动自动识别nacos服务(约定大于配置)routes: #路由数组[路由 就是指定当请求满足什么条件的时候转到哪个微服务]- id: product_route #当前路由的标识,要求唯-uri: http://localhost:8086 #请求要转发到的地址order: 1 #路由的优先级,数字越小级别越高predicates: #断言(就是路由转发要满足的条件)- Path=/product-service/**,/ddd/s #当请求路径满足Path指定的规则时,才进行路由转发- Before=2024-08-20T17:42:47.789-07:00[America/Denver]- CheckAuth=zhangSan1filters: #过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改- StripPrefix=1 #转发之前去掉1层路径,

查看网关各种局部过滤器官网

自定义网关过滤器和自定义断言都全部类似

继承AbstractNameValueGatewavFilterFactory日我们的自定义名称必须要以GatewavFiterFactorv结尾并交给spring管理

package com.test.gate.config;import com.alibaba.nacos.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;import java.util.Arrays;
import java.util.List;/*** @Description:* @Author: xu* @Data: 2024-2024/4/12-11* @Version: V1.0*/
@Componentpublic class CheckAuthGatewayFilterFactory extends AbstractGatewayFilterFactory<CheckAuthGatewayFilterFactory.Config> {private static Logger log = LoggerFactory.getLogger(CheckAuthGatewayFilterFactory.class);public List<String> shortcutFieldOrder() {return Arrays.asList("name");}@Overridepublic GatewayFilter apply(Config config) {return (exchange, chain) -> {log.info("调用checkAuthGatewayFilterFactory==="+ config.getName());String name = exchange.getRequest().getQueryParams().getFirst("name");if (StringUtils.isNotBlank(name)) {if (config.getName().equals(name)) {chain.filter(exchange);} else {//返回404exchange.getResponse().setStatusCode(HttpStatus.NOT_FOUND);exchange.getResponse().setComplete();}//1 正常请求chain.filter(exchange);}return null;};}public static class Config {private String name;public Config() {}public String getName() {return this.name;}public void setName(String prefix) {this.name = name;}}
}
server:port: 8087
spring:application:name: gateway-nacoscloud:nacos:discovery:server-addr: 192.168.11.47:18848username: nacospassword: nacosgateway:
#      discovery:
#        locator:
#          enabled: true    #是否启动自动识别nacos服务(约定大于配置)routes: #路由数组[路由 就是指定当请求满足什么条件的时候转到哪个微服务]- id: product_route #当前路由的标识,要求唯-uri: http://localhost:8086 #请求要转发到的地址order: 1 #路由的优先级,数字越小级别越高predicates: #断言(就是路由转发要满足的条件)- Path=/product-service/**,/ddd/s #当请求路径满足Path指定的规则时,才进行路由转发- Before=2024-08-20T17:42:47.789-07:00[America/Denver]- CheckAuth=zhangSan1filters: #过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改- StripPrefix=1 #转发之前去掉1层路径,- CheckAuth=lisi

全局过滤器(Global Filters)配置

在这里插入图片描述

自定义全局过滤器(Global Filters)配置类(一般都是实现认证或者授权,或者做日记记录,不需要在配置文件做任何配置)

package com.test.gate.config;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;/*** @Description:* @Author: xu* @Data: 2024-2024/4/12-20* @Version: V1.0*/
@Component
public class LogGlobalFilter implements GlobalFilter {private static Logger log = LoggerFactory.getLogger(LogGlobalFilter.class);@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {//做业务处理,授权或者日记记录log.info(exchange.getRequest().getPath().value());return chain.filter(exchange);}
}

要启用 Reactor Netty 访问日志,请设置-Dreactor,netty.http,server.accessLogEnabled=true,它必须是 Java 系统属性,而不是 Spring Boot 属性。如果是jar包启动,就将网关打包成jar包,如下运行

java -jar gateway.jar -Dreactor,netty.http,server.accessLogEnabled=true

idea配置网关日记打印,在vm配置 -Dreactor.netty.http.server.accessLogEnabled=true

在这里插入图片描述

将网关日志记录全部输出到日志文件。以下示例创建一个Logback.xml 配置

<?xml version="1.0" encoding="UTF-8"?>
<configuration><!-- 控制台输出 --><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern></encoder></appender><!-- 按天滚动的文件输出 --><appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>G:\temptemptemp\gatewaylog\logfile.log</file> <!-- 修改为你想要保存日志文件的路径 --><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>G:\temptemptemp\gatewaylog\logfile.%d{yyyy-MM-dd}.log</fileNamePattern> <!-- 指定按日期滚动的文件名格式 --><maxHistory>30</maxHistory> <!-- 保留最多30天的历史日志文件 --></rollingPolicy><encoder><pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern></encoder></appender><!-- 异步日志输出 --><appender name="async" class="ch.qos.logback.classic.AsyncAppender"><appender-ref ref="ROLLING_FILE"/> <!-- 将异步 appender 链接到文件输出 --></appender><!-- 记录器配置 --><logger name="reactor.netty.http.server.AccessLog" level="INFO" additivity="false"><appender-ref ref="async"/> <!-- 将异步 appender 应用于特定的日志记录器 --><appender-ref ref="STDOUT"/> <!-- 控制台输出 --></logger><!-- 根日志级别设置 --><root level="info"><appender-ref ref="STDOUT"/> <!-- 控制台输出 --><appender-ref ref="ROLLING_FILE"/> <!-- 将按天滚动的文件输出器添加到根输出器中 --></root></configuration>

Gateway跨域配置(CORS Configuration),网关官网跨域配置

方法一:yml配置文件配置跨域

spring:cloud:gateway:globalcors:cors-configurations:'[/**]':  #运行跨域访问的资源allowedOrigins: "https://docs.spring.io"  #跨域允许来源allowedMethods:- GET- POST

方法二:通过配置类设置跨域(注意UrlBasedCorsConfigurationSource 导入的包是import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource)

package com.test.gate.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
import org.springframework.web.util.pattern.PathPatternParser;/*** @Description:* @Author: xu* @Data: 2024-2024/4/12-22* @Version: V1.0*/
@Configuration
public class CorsConfig {@Beanpublic CorsWebFilter corsFilter() {CorsConfiguration config = new CorsConfiguration();config.addAllowedMethod("*");config.addAllowedOrigin("*");config.addAllowedHeader("*");UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());source.registerCorsConfiguration("/**", config);return new CorsWebFilter(source);}
}

网关限流整合sentinel官网

pom.xml添加依赖整合sentinel,和官网配置的有以下不一样是因为spring-cloud-alibaba-sentinel-gateway这个依赖比adapter依赖多了SentinelSCGAutoConfiguration自定注入例如很多需要的bean

<!--sentinel整台gateway  以前版本使用adapter-->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
<!--sentinel的依赖-->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

配置文件配置sentinel

#   配置sentinelsentinel:transport:dashboard: 127.0.0.1:8858   #sentiel的dashboard地址

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

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

相关文章

rhce day1

一 . 在系统中设定延迟任务要求如下 在系统中建立 easylee 用户&#xff0c;设定其密码为 easylee 延迟任务由 root 用户建立 要求在 5 小时后备份系统中的用户信息文件到 /backup 中 确保延迟任务是使用非交互模式建立 确保系统中只有 root 用户和 easylee 用户可以执行延…

线性表概念及顺序表的实现

文章目录 前言一、线性表1.定义2.特点3.一般线性表的抽象数据类型定义 二、线性表的顺序存储&#xff08;顺序表&#xff09;1.基本概念2.数组实现顺序表3.顺序表中基本操作的具体实现4.顺序表总结 总结 前言 T_T此专栏用于记录数据结构及算法的&#xff08;痛苦&#xff09;学…

Golang教程一(环境搭建,变量,数据类型,数组切片map)

目录 一、环境搭建 1.windows安装 2.linux安装 3.开发工具 二、变量定义与输入输出 1.变量定义 2.全局变量与局部变量 3.定义多个变量 4.常量定义 5.命名规范 6.输出 格式化输出 7.输入 三、基本数据类型 1.整数型 2.浮点型 3.字符型 4.字符串类型 转义字…

计算机网络(四)网络层

网络层 基本概念 网络互联&#xff1a; 将两个以上的计算机网络&#xff0c;通过一定的办法&#xff0c;用一种或多种通信处理设备(即中间设备)相互连接起来&#xff0c;以构成更大的网络系统。中间设备又称中间系统或中继系统 中继系统分为4种&#xff1a; 物理层中继系统…

Navicat的安装与破解

个人介绍 hello hello~ &#xff0c;这里是 code袁~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f981;作者简介&#xff1a;一名喜欢分享和记录学习的…

EI级 | Matlab实现TCN-LSTM-MATT、TCN-LSTM、TCN、LSTM多变量时间序列预测对比

EI级 | Matlab实现TCN-LSTM-MATT、TCN-LSTM、TCN、LSTM多变量时间序列预测对比 目录 EI级 | Matlab实现TCN-LSTM-MATT、TCN-LSTM、TCN、LSTM多变量时间序列预测对比预测效果基本介绍程序设计参考资料 预测效果 基本介绍 【EI级】Matlab实现TCN-LSTM-MATT、TCN-LSTM、TCN、LSTM…

Unity 扩展自定义编辑器窗口

在Assets文件夹路径下任意位置创建Editor文件夹&#xff0c;将扩展编辑器的代码放在Editor文件夹下 生成编辑器窗口 代码中首先引用命名空间 using UnityEditor; 然后将创建的类继承自EditorWindow public class MenuEditor : EditorWindow 然后通过扩展编辑器菜单功能调用…

AI - 提示词意外收获 (5)

提示词&#xff1a; A soft pink rose with opalescent leaves, located in a surreal desert under the light of a binary star system, The dual shadows and contrasting lights create a dreamlike quality, emphasizing the roses unique beauty,翻译: 一种柔软的粉红…

动态规划|343.整数拆分

力扣题目链接 class Solution { public:int integerBreak(int n) {vector<int> dp(n 1);dp[2] 1;for (int i 3; i < n ; i) {for (int j 1; j < i / 2; j) {dp[i] max(dp[i], max((i - j) * j, dp[i - j] * j));}}return dp[n];} }; 思路 看到这道题目&…

153. 寻找旋转排序数组中的最小值

Problem: 153. 寻找旋转排序数组中的最小值 文章目录 思路解题方法复杂度Code 思路 排序( O ( n l o g n ) O(nlogn) O(nlogn)) 或者 循环一次( O ( n ) O(n) O(n))&#xff0c;但时间复杂度均不满足要求 解题方法 二分 当数组旋转后&#xff0c;只有可能出现如图的两种情况&am…

数据库查询:查询入参类型和数据库字段类型不匹配导致的问题

问题&#xff1a;假设我们现在有这样的一张表 CREATE TABLE test_person (id int(20) NOT NULL COMMENT 主键,name varchar(20) DEFAULT NULL COMMENT 姓名,gender char(2) DEFAULT NULL COMMENT 性别,birthday date DEFAULT NULL COMMENT 生日,created_time timestamp NULL D…

ubuntu 23.10.1 mysql 安装

注&#xff1a;请进入root用户模式下操作&#xff0c;若没有&#xff0c;输入命令前加上sudo 1、更新软件包列表 apt update2、安装最新版的Mysql服务器 apt install mysql-server -y如果不加-y 会在安装过程中&#xff0c;系统将提示你设置MySQL的root密码。确保密码足够强…

《云原生安全攻防》-- 云原生攻防矩阵

在本节课程中&#xff0c;我们将开始学习如何从攻击者的角度思考&#xff0c;一起探讨常见的容器和K8s攻击手法&#xff0c;包含以下两个主要内容&#xff1a; 云原生环境的攻击路径: 了解云原生环境的整体攻击流程。 云原生攻防矩阵: 云原生环境攻击路径的全景视图&#xff0…

Unity解决:导出安卓apk 安装时报错:应用未安装:软件包似乎无效

Unity2018.4.36 导出安卓apk 安装时报错&#xff1a;应用未安装&#xff1a;软件包似乎无效 解决办法&#xff1a;因为安装到安卓12 需要添加添加过滤规则 在AS工程AndroidManifest.xml 添加过滤规则即可。 android:exported"true"

记录flume运行时报NullPointerException异常

【背景说明】 我要起一个将kafka上的topic_log主题中的数据上传到hdfs上的flume进程。 这是我的flume配置文件脚本&#xff1a; #定义组件 a1.sourcesr1 a1.channelsc1 a1.sinksk1#配置source1 a1.sources.r1.type org.apache.flume.source.kafka.KafkaSource a1.sources.r…

使用 npm 工具高效更新项目依赖包

团队内部会用工具定时检查包的最新版本并通知&#xff0c;以便我们及时跟进社区进展&#xff0c;避免和技术栈出现版本脱节导致无法使用最新特性和优化内容 这里只说明手动查看和更新包的主要几个命令。 npm outdated&#xff1a;检查项目中过时的依赖包及其最新版本。 npm i…

MVSplat:稀疏多视点图像的高效3D高斯溅射

MVSplat: Efficient 3D Gaussian Splatting from Sparse Multi-View Images MVSplat&#xff1a;稀疏多视点图像的高效3D高斯溅射 Yuedong Chen1  Haofei Xu2,3  Chuanxia Zheng4  Bohan Zhuang 粤东陈浩飞徐 2,3 郑传霞 4 庄伯涵1 Marc Pollefeys2,5  Andreas Geiger3  T…

如何应对孩子情绪化地发脾气?

你有小孩儿吗&#xff1f;是否受孩子发脾气的困扰&#xff1f;如果都没有&#xff0c;可以跳出去看看别人的文章了&#xff0c;如果有&#xff0c;可以继续往下看。 白牙有个小闺女&#xff0c;3 岁半&#xff0c;今天她看大人洗脚&#xff0c;她也想洗&#xff0c;但没来得及给…

[lesson31]完善的复数类

完善的复数类 完善的复数类 复数类应该具有的操作 运算&#xff1a;&#xff0c;-&#xff0c;*&#xff0c;/比较&#xff1a;&#xff0c;!赋值&#xff1a;求模&#xff1a;modulus 利用操作符重载 统一复数与实数的运算方式统一复数与实数的比较方式 注意事项 C规定赋…

HarmonyOS开发实例:【事件的订阅和发布】

介绍 本示例主要展示了公共事件相关的功能&#xff0c;实现了一个检测用户部分行为的应用。具体而言实现了如下几点功能&#xff1a; 1.通过订阅系统公共事件&#xff0c;实现对用户操作行为&#xff08;亮灭屏、锁屏和解锁屏幕、断联网&#xff09;的监测&#xff1b; 2.通…