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

spring-bus消息总线的使用

文章目录

  • 依赖
  • bus应用
    • 接口
    • 用到的封装参数类
  • 接收的应用
    • 监听器
    • 定义的事件类
  • 使用bus
    • 定义bus远程调用
    • A应用数据更新后通过bus数据同步给B应用

依赖

   <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bus-amqp</artifactId></dependency>

bus应用

  • 类似于生产者

接口

  • 供内部其他应用使用,远程调用该接口实现各应用之间数据同步
  • 参数1定义事件,参数2定义操作具体crud,参数3定义传参数据,参数4定义给哪个应用(nacos注册的应用名)同步数据
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.xyc.sms.common.bus.events.DataSyncEventEnum;
import com.xyc.sms.common.bus.events.DataSyncEventFactory;
import com.xyc.sms.common.bus.events.DataSyncOperateTypeEnum;
import com.xyc.sms.common.entity.Result;
import org.springframework.cloud.bus.ServiceMatcher;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;/*** 数据同步通知事件控制器,该事件主要用于平台中常规的数据同步通知,* 需要用于其他功能请新增类* 需要增加同步的方式请在{@link DataSyncEventEnum}增加事件枚举* 同时在{@link com.xyc.sms.common.bus.events.dataSync}下增加事件类,新增的事件类需要继承{@link com.xyc.sms.common.bus.events.DataSyncEvent}*/
@RestController
@RequestMapping("/default")
public class DataSyncNotifyEventController {private static final Log logger = LogFactory.get();@Resourceprivate ServiceMatcher busServiceMatcher;@Resourceprivate ApplicationEventPublisher applicationEventPublisher;/*** 发布数据同步通知事件** @param eventEnum   事件枚举,可通过枚举找到对应的事件类* @param operateType 操作类型枚举* @param obj         需要处理的消息* @param destination 目的地,为null则是广播给所有该事件的监听器* @return 发布结果*/@PostMapping("/publish/{eventEnum}/{operateType}")public Result publishDataSyncNotifyEvent(@PathVariable("eventEnum") DataSyncEventEnum eventEnum,@PathVariable("operateType") DataSyncOperateTypeEnum operateType,@RequestBody Object obj,@RequestParam(value = "destination", required = false) String destination) {try {applicationEventPublisher.publishEvent(DataSyncEventFactory.getInstanceForEvent(eventEnum,operateType,obj,busServiceMatcher.getServiceId(),destination));return Result.returnSuccessWithMsg("success");} catch (Exception e) {logger.error(e);return Result.returnFail(e.getMessage());}}
}
  • 事件工厂类
import com.fasterxml.jackson.databind.ObjectMapper;import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;public class DataSyncEventFactory {private static final ObjectMapper OM = new ObjectMapper();/*** 通过事件的类模板获取构造器并调用,生成事件的实体类** @param operateType        操作类型* @param source             事件原数据* @param originService      原服务* @param destinationService 目标服务* @return 事件实体类* @throws NoSuchMethodException     通过类模板无法找到相应的构造方法所抛出的异常* @throws InvocationTargetException 构造器创建实例可能出现的调用目标异常* @throws InstantiationException    构造器创建实例可能出现的实例化异常* @throws IllegalAccessException    构造器创建实例可能出现的无法访问异常* @throws IOException               json转化出现IO的异常* @throws ClassNotFoundException    通过类名{@link DataSyncEventEnum#getEventClassName()}没有找到对应类*/public static DataSyncEvent<?> getInstanceForEvent(DataSyncEventEnum eventEnum,DataSyncOperateTypeEnum operateType,Object source,String originService,String destinationService)throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, IOException, ClassNotFoundException {Constructor<?>[] constructors = DataSyncEventFactory.getEventClass(eventEnum).getDeclaredConstructors();Constructor<?> constructor = Arrays.stream(constructors).filter(c -> c.getParameterCount() == 4).findFirst().orElseThrow(NoSuchMethodException::new);// 值转化Object o = OM.readValue(OM.writeValueAsString(source), constructor.getParameterTypes()[1]);return (DataSyncEvent<?>) constructor.newInstance(operateType, o, originService, destinationService);}private static Class<?> getEventClass(DataSyncEventEnum eventEnum) throws ClassNotFoundException {return Class.forName(eventEnum.getEventClassName());}
}

用到的封装参数类

在这里插入图片描述

  • 定义各事件的枚举(只定义全类限定名称)
public enum DataSyncEventEnum {/*** 黑名单同步,参数为事件的类型名,注意需要使用全限定类名* @see com.xyc.sms.common.bus.events.dataSync.BlackListSyncEvent*/BLACKLIST_SYN("com.xyc.sms.common.bus.events.dataSync.BlackListSyncEvent"),/*** 路由同步* @see com.xyc.sms.common.bus.events.dataSync.RouteSyncEvent*/ROUTE_SYN("com.xyc.sms.common.bus.events.dataSync.RouteSyncEvent");/*** 事件类型名* @see DataSyncEvent 该抽象类的实现类*/private final String eventClassName;DataSyncEventEnum(String eventClassName) {this.eventClassName = eventClassName;}public String getEventClassName() {return eventClassName;}
}
  • 定义crud操作枚举
public enum DataSyncOperateTypeEnum implements Serializable {ADD, UPD, DEL
}
  • 推送的事件类
/*** 数据同步通知事件,作为一般通用事件使用,如需要特殊处理建议新增事件*/
public abstract class DataSyncEvent<T> extends RemoteApplicationEvent {/*** 事件数据*/private DataSync<T> dataSync;public DataSync<T> getDataSync() {return dataSync;}public void setDataSync(DataSync<T> dataSync) {this.dataSync = dataSync;}/*** 基础构造器** @param source             引发事件的原始数据* @param originService      引发事件的原始服务* @param destinationService 事件的目标服务*/public DataSyncEvent(DataSync<T> source, String originService, String destinationService) {super(source, originService, destinationService);this.dataSync = source;}/*** 事件的日志打印,会在监听器监听到事件时输出打印* 结果尽可能不要有换行,保证日志输出在一行内* 该方法可以在子类中重写** @return 日志*/public String logPrint() {return String.format("{\"originService\":\"%s\",\"destinationService\":\"%s\",\"id\":\"%s\",\"dataSync\":%s,\"timestamp\":\"%s\"}", this.getId(), this.getOriginService(), this.getDestinationService(), Objects.nonNull(this.dataSync) ? this.dataSync.toString() : "null", this.getTimestamp());}/*** 数据同步的原始数据封装*/public static class DataSync<T> implements Serializable {private DataSyncOperateTypeEnum operateType;private T data;public DataSync() {}public DataSync(DataSyncOperateTypeEnum operateType, T data) {this.operateType = operateType;this.data = data;}public DataSyncOperateTypeEnum getOperateType() {return operateType;}public T getData() {return data;}@Overridepublic String toString() {return "{\"operateType\":" +operateType+ ",\"data\":" +data+ "}";}}
}
  • 应用枚举
/*** 服务枚举*/
public enum ServiceEnum {SMS_BLACK_API("sms-black-api"),SMS_RULES("sms-rules");public final String serviceName;ServiceEnum(String serviceName) {this.serviceName = serviceName;}
}

接收的应用

  • 类似于消费者

监听器

  • 推送过来的操作枚举类crud的值,决定执行哪个crud的具体方法
  • 该类放在接收的应用中,其他顶部继承的类放在common包中即可
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.xyc.sms.common.bus.DataSyncListener;
import com.xyc.sms.common.bus.events.dataSync.RouteSyncEvent;
import com.xyc.sms.common.entity.sms.Route;
import com.xyc.sms.rules.dao.boss.RouteMapper;
import com.xyc.sms.rules.data.RuleSymbol;
import com.xyc.sms.rules.service.SynService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;/*** 路由同步通知监听器*/
@Component
public class RouteSynNotifyListener extends DataSyncListener<RouteSyncEvent, List<Route>> {private static final Log log = LogFactory.get();@Autowiredprivate RouteMapper routeMapper;@Autowiredprivate SynService synService;@Overridepublic void handleByADD(List<Route> data) {Optional.ofNullable(data).ifPresent(ls -> {if (ls.isEmpty()) {return;}long l = System.currentTimeMillis();String time = DateUtil.formatDateTime(ls.get(0).getCreateTime());List<Route> list = routeMapper.selectByCreatetime(time);if (CollectionUtil.isEmpty(list)) {return;}// 加载到内存中list.forEach(r -> RuleSymbol.RouteMap.put(r.getId(), r));synService.transformRoute(list, (s, r) -> RuleSymbol.RouteChannelMap.put(s, r));log.info("RouteSynNotifyListener - {} - add | createTime:{}", (System.currentTimeMillis() - l), time);});}@Overridepublic void handleByUPD(List<Route> data) {// 流程还是先删除后新增的方式Optional.ofNullable(data).ifPresent(ls -> {List<Integer> collect = ls.stream().map(Route::getId).filter(Objects::nonNull).collect(Collectors.toList());if (collect.isEmpty()) {return;}long l = System.currentTimeMillis();// 如果有,先删除List<Route> c = collect.stream().map(RuleSymbol.RouteMap::get).filter(Objects::nonNull).collect(Collectors.toList());if (!c.isEmpty()) {synService.transformRoute(c, (s, r) -> RuleSymbol.RouteChannelMap.remove(s, r));}// 如果有,再加入List<Route> list = routeMapper.selectById(collect);if (!list.isEmpty()) {list.forEach(r -> RuleSymbol.RouteMap.put(r.getId(), r));synService.transformRoute(list, (s, r) -> RuleSymbol.RouteChannelMap.put(s, r));}log.info("RouteSynNotifyListener - {} - update | {}", (System.currentTimeMillis() - l), collect);});}@Overridepublic void handleByDEL(List<Route> data) {Optional.ofNullable(data).ifPresent(ls -> {long l = System.currentTimeMillis();List<Route> collect = ls.stream().map(r -> RuleSymbol.RouteMap.remove(r.getId())).filter(Objects::nonNull).collect(Collectors.toList());if (collect.isEmpty()) {return;}synService.transformRoute(collect, (s, r) -> RuleSymbol.RouteChannelMap.remove(s));log.info("RouteSynNotifyListener - {} - remove", (System.currentTimeMillis() - l));});}
}
  • 继承的抽象监听类
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.xyc.sms.common.bus.events.DataSyncEvent;
import org.springframework.context.ApplicationListener;/*** 数据同步事件监听器* 需要具体的子类实现,并注册到spring容器中** @param <T> 数据同步件*/
public abstract class DataSyncListener<T extends DataSyncEvent<D>, D> implements ApplicationListener<T> {private static final Log logger = LogFactory.get();@Overridepublic void onApplicationEvent(T event) {logger.info("[DataSyncListener][onApplicationEvent] trigger event - {} - {}", event.getClass().getName(), event.logPrint());try {triggerEvent(event);} catch (Exception e) {logger.error(e);}}/*** 触发监听,处理事件** @param event 事件*/public void triggerEvent(T event) {DataSyncEvent.DataSync<D> source = event.getDataSync();switch (source.getOperateType()) {case ADD:handleByADD(source.getData());return;case UPD:handleByUPD(source.getData());return;case DEL:handleByDEL(source.getData());return;default:}}/*** 处理添加事件* 由子类实现** @param data 需要处理的数据*/public abstract void handleByADD(D data);/*** 处理修改事件* 由子类实现** @param data 需要处理的数据*/public abstract void handleByUPD(D data);/*** 处理删除事件* 由子类实现** @param data 需要处理的数据*/public abstract void handleByDEL(D data);
}

定义的事件类

  • 上面封装的事件枚举所记录的是该类的全类限定名称
package com.xyc.sms.common.bus.events.dataSync;import com.xyc.sms.common.bus.events.DataSyncEvent;
import com.xyc.sms.common.bus.events.DataSyncOperateTypeEnum;
import com.xyc.sms.common.entity.sms.Route;import java.util.List;public class RouteSyncEvent extends DataSyncEvent<List<Route>> {private static final long serialVersionUID = -501657066268464154L;public RouteSyncEvent(DataSyncOperateTypeEnum operateType, List<Route> Routes, String originService, String destinationService) {super(new DataSync<>(operateType, Routes), originService, destinationService);}
}
  • 继承的抽象事件类
/*** 数据同步通知事件,作为一般通用事件使用,如需要特殊处理建议新增事件*/
public abstract class DataSyncEvent<T> extends RemoteApplicationEvent {/*** 事件数据*/private DataSync<T> dataSync;public DataSync<T> getDataSync() {return dataSync;}public void setDataSync(DataSync<T> dataSync) {this.dataSync = dataSync;}/*** 基础构造器** @param source             引发事件的原始数据* @param originService      引发事件的原始服务* @param destinationService 事件的目标服务*/public DataSyncEvent(DataSync<T> source, String originService, String destinationService) {super(source, originService, destinationService);this.dataSync = source;}/*** 事件的日志打印,会在监听器监听到事件时输出打印* 结果尽可能不要有换行,保证日志输出在一行内* 该方法可以在子类中重写** @return 日志*/public String logPrint() {return String.format("{\"originService\":\"%s\",\"destinationService\":\"%s\",\"id\":\"%s\",\"dataSync\":%s,\"timestamp\":\"%s\"}", this.getId(), this.getOriginService(), this.getDestinationService(), Objects.nonNull(this.dataSync) ? this.dataSync.toString() : "null", this.getTimestamp());}/*** 数据同步的原始数据封装*/public static class DataSync<T> implements Serializable {private DataSyncOperateTypeEnum operateType;private T data;public DataSync() {}public DataSync(DataSyncOperateTypeEnum operateType, T data) {this.operateType = operateType;this.data = data;}public DataSyncOperateTypeEnum getOperateType() {return operateType;}public T getData() {return data;}@Overridepublic String toString() {return "{\"operateType\":" +operateType+ ",\"data\":" +data+ "}";}}
}

使用bus

  • 引用注入bus应用的接口远程调用

定义bus远程调用

@FeignClient(value="sms-bus", fallbackFactory = DataSyncNotifyEventServiceFallbackFactory.class)
public interface DataSyncNotifyEventService {/*** 发布数据同步通知事件* destination 参数被删除,不需要指定服务** @param eventEnum   事件枚举,可通过枚举找到对应的事件类* @param operateType 操作类型枚举* @param obj         需要处理的消息* @return 发布结果*/@PostMapping("/default/publish/{eventEnum}/{operateType}")Result publishDataSyncNotifyEvent(@PathVariable("eventEnum") DataSyncEventEnum eventEnum,@PathVariable("operateType") DataSyncOperateTypeEnum operateType,@RequestBody Object obj,@RequestParam("destination") String destination);
}
  • 注入使用
    在这里插入图片描述

A应用数据更新后通过bus数据同步给B应用

  • 在A应用的业务层写以下代码
 try {result = dataSyncNotifyEventService.publishDataSyncNotifyEvent(DataSyncEventEnum.ROUTE_SYN,DataSyncOperateTypeEnum.ADD,new ArrayList<Route>() {{Route r = new Route();r.setCreateTime(date);add(r);}}, ServiceEnum.SMS_RULES.serviceName);log.info("新增路由调用通知同步所有服务 result:{}", result);} catch (Exception e) {log.error("同步异常 {}", result, e);}

相关文章:

spring-bus消息总线的使用

文章目录 依赖bus应用接口用到的封装参数类 接收的应用监听器定义的事件类 使用bus定义bus远程调用A应用数据更新后通过bus数据同步给B应用 依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bus-amqp…...

isctf---re

crackme 解压得到crackme.exe 运行得到flag babyRe 先猜e65537的rsa 先用Z3强行求出p、q&#xff0c;算出常规rsa中的phi&#xff0c;然后套用公式求出m exp #babyre wp from z3 import * import libnum from Crypto.Util.number import * p,q,cInts(p q c) S Solver() S…...

C语言第十二弹--扫雷

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 扫雷 1、扫雷游戏分析和设计 1.1、扫雷游戏的功能说明 1.2 游戏的分析和设计 1.2.1、数据结构的分析 1.2.2、文件结构设计 2、扫雷游戏的结构分析 2.1、用…...

网路服务器——线程池技术

文章目录 一、线程池技术二、使用原理三、优点总结 一、线程池技术 预创建原则&#xff0c;线程池内部准备线程备用&#xff0c; 不宜过多。线程应该重用性&#xff0c;可以一对多处理任务或服务不同的客户端。处理单元(线程)数量并不固定&#xff0c;动态扩容与缩减(任务量)。…...

探索设计模式的魅力:深入了解适配器模式-优雅地解决接口不匹配问题

设计模式专栏&#xff1a;http://t.csdnimg.cn/nolNS 目录 一、引言 1. 概述 2. 为什么需要适配器模式 3. 本文的目的和结构 二、简价 1. 适配器模式的定义和特点 定义 特点 2. 适配器模式的作用和适用场景 作用 适用场景 3. 适配器模式与其他设计模式的比较 三、适配…...

matlab窗函数-hann窗和hamming窗函数

窗函数的作用 在时域上&#xff0c;窗函数可以看作是对原始信号进行截断或调制的加权函数。这些窗函数通常在时域上是有限的宽度&#xff0c;并且具有对称性&#xff0c;如矩形窗、汉宁窗、汉明窗和布莱克曼窗等。例如&#xff0c;汉明窗是一种对称窗函数&#xff0c;它可以用…...

Java项目实战--瑞吉外卖DAY03

目录 P22新增员工_编写全局异常处理器 P23新增员工_完善全局异常处理器并测试 p24新增员工_小结 P27员工分页查询_代码开发1 P28员工分页查询_代码开发2 P22新增员工_编写全局异常处理器 在COMMON新增全局异常捕获的类&#xff0c;其实就是代理我们这些controlle。通过aop把…...

docker 里使用vcs 2018 verdi等eda 图形界面

书接上文。之前借用别人的docker&#xff0c;使用EDA工具&#xff0c;苦于没有图形界面。如果只是编码&#xff0c;编译可能问题不大&#xff0c;但是如果要看波形之类的&#xff0c;就没法实现了。 docker 使用 vcs/2018 Verdi等 eda 软件-CSDN博客https://blog.csdn.net/guy…...

OpenHarmony—不支持解构赋值

规则&#xff1a;arkts-no-destruct-assignment 级别&#xff1a;错误 ArkTS不支持解构赋值。可使用其他替代方法&#xff0c;例如&#xff0c;使用临时变量。 TypeScript let [one, two] [1, 2]; // 此处需要分号 [one, two] [two, one];let head, tail [head, ...tail]…...

让AI帮你说话--GPT-SoVITS教程

有时候我们在录制视频的时候&#xff0c;由于周边环境嘈杂或者录音设备问题需要后期配音&#xff0c;这样就比较麻烦。一个比较直观的想法就是能不能将写好的视频脚本直接转换成我们的声音&#xff0c;让AI帮我们完成配音呢&#xff1f;在语音合成领域已经有很多这类工作了&…...

线性回归需要满足的几个假设

线性回归模型是基于一些假设构建的&#xff0c;这些假设有助于确保模型的有效性和可解释性。以下是线性回归需要满足的几个主要假设&#xff1a; 线性关系假设&#xff08;Linearity&#xff09;: 线性回归假设因变量&#xff08;目标变量&#xff09;与自变量&#xff08;特征…...

go语言(十八)---- goroutine

一、goroutine package mainimport ("fmt""time" )func main() {//用go创建承载一个形参为空&#xff0c;返回值为空的一个函数go func() {defer fmt.Println("A.defer")func() {defer fmt.Println("B.defer")//退出当前goroutinefmt…...

城市开发区视频系统建设方案:打造视频基座、加强图像数据治理

一、背景需求 随着城市建设的步伐日益加快&#xff0c;开发区已经成为了我国工业化、城镇化和对外开放的重要载体。自贸区、开发区和产业园的管理工作自然也变得至关重要。在城市经开区的展览展示馆、进出口商品展示交易中心等地&#xff0c;数千路监控摄像头遍布各角落&#…...

宏景eHRSmsAcceptGSTXServle存在XXE漏洞

指纹特征 app"HJSOFT-HCM"漏洞复现 POST /servlet/sms/SmsAcceptGSTXServlet HTTP/1.1 Host: User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36 Content-Length: 137 Content…...

LLVM实战之模块化设计

目录 1. llvm基础理念 2. 准备工作 3. 详细步骤 3.1 指令合并优化 3.2 无用参数消除优化 4. Pass管理器(Pass Manager)...

可以运行在浏览器的Windows 2000

Windows 2000 可以在浏览器里跑了&#xff0c;缺点就是速度慢。 JSLinux JSLinux 在浏览器中运行 Linux 或其他操作系统&#xff01; 可以使用以下仿真系统&#xff1a; 中央处理器操作系统用户 界面VF同步 访问启动 链接TEMU 配置评论x86阿尔派Linux 3.12.0安慰是的点击这…...

CUDA笔记

CUDA笔记 nvidia-smi 命令使用 nvidiasmi -q&#xff1a;查询GPU详细信息&#xff1b; nvidia-smi -q -l 0&#xff1a;查询特定GPU详细信息&#xff1b; nvidia-smi -q -l 0 -d MEMORY&#xff1a;显示GPU特定信息&#xff1b; nvidia-smi -h&#xff1a;英伟达的帮助命令。…...

Open CASCADE学习| ​提取曲面的PCurve

PCurve这个概念&#xff0c;字面上来理解就是参数曲线&#xff08;Parametric Curve&#xff09;。参数空间曲线是在参数曲面的双参数空间中的二维样条曲线。 二维曲线定义的目的只有一个&#xff1a;pCurve&#xff0c;参数曲线。OCC采用参数法构建几何结构&#xff0c;所有的…...

GMS测试BTSfail-CVE-2022-20451

描述&#xff1a; 项目需要过GMS兼容性测试&#xff0c;BTS这块我们环境没有&#xff0c;送检之后出现了一个BTS的Alert&#xff0c;这个是必须要解决的。下面的warning可以不考虑。 这个是patch问题&#xff0c;根据代理提供的pdf文件找到一个id:为A-235098883的补丁&#xf…...

Vue学习笔记12--Vue3之setup/ref函数/reactive函数/Vue3响应式原理/reactive对比ref

一、拉开序幕的setup 理解&#xff1a;Vue3中一个新的配置项&#xff0c;值为一个函数。setup是所有Composition API(组合API&#xff09;表演的舞台。组件中所用到的&#xff1a;数据、方法等&#xff0c;均要配置在setup中。setup函数的两种返回值&#xff1a; 若返回一个对…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

Android15默认授权浮窗权限

我们经常有那种需求&#xff0c;客户需要定制的apk集成在ROM中&#xff0c;并且默认授予其【显示在其他应用的上层】权限&#xff0c;也就是我们常说的浮窗权限&#xff0c;那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统

目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索&#xff08;基于物理空间 广播范围&#xff09;2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

windows系统MySQL安装文档

概览&#xff1a;本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容&#xff0c;为学习者提供全面的操作指导。关键要点包括&#xff1a; 解压 &#xff1a;下载完成后解压压缩包&#xff0c;得到MySQL 8.…...

Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?

Pod IP 的本质与特性 Pod IP 的定位 纯端点地址&#xff1a;Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址&#xff08;如 10.244.1.2&#xff09;无特殊名称&#xff1a;在 Kubernetes 中&#xff0c;它通常被称为 “Pod IP” 或 “容器 IP”生命周期&#xff1a;与 Pod …...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...

书籍“之“字形打印矩阵(8)0609

题目 给定一个矩阵matrix&#xff0c;按照"之"字形的方式打印这个矩阵&#xff0c;例如&#xff1a; 1 2 3 4 5 6 7 8 9 10 11 12 ”之“字形打印的结果为&#xff1a;1&#xff0c;…...