SpringCloudAlibaba技术栈-Dubbo

news2024/12/27 11:30:19

1、什么是Dubbo?

简单来说,dubbo就像是个看不见的手,负责专门从注册中心nacos调用注册到nacos上面的服务的,因为在微服务环境下不同的功能模块可能在不同的服务器上。dubbo调用服务就像是在调用本地的服务一样。

分布式调用与高并发处理 Dubbo分布式调用_分布式之间的调用-CSDN博客

2、Dubbo实现

(1)创建父项目

添加相关依赖

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zj</groupId>
    <artifactId>Dubbo_demo2</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>Dubbo_demo2</name>
    <url>http://maven.apache.org</url>

    <properties>
        <dubbo.version>3.2.4</dubbo.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>17</java.version>
        <spring-boot.version>3.0.2</spring-boot.version>
        <spring-cloud.version>2022.0.0</spring-cloud.version>
        <spring-cloud-alibaba.version>2022.0.0.0</spring-cloud-alibaba.version>
        <lombok.version>1.8.28</lombok.version>
    </properties>


    <dependencyManagement>
        <dependencies>


            <!-- SpringCloud 微服务 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>


            <!-- SpringCloud Alibaba 微服务 -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>


            <!-- SpringBoot 依赖配置 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- lombok 依赖配置 -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}}</version>
            </dependency>


            <!-- Dubbo -->
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-bom</artifactId>
                <version>${dubbo.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>


            <!-- bootstrap 启动器 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-bootstrap</artifactId>
            </dependency>


            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>3.8.1</version>
                <scope>test</scope>
            </dependency>

        </dependencies>

    </dependencyManagement>

</project>

(2)创建子模块interface

添加下面的依赖文件,为啥要添加mybatis依赖呢?因为有些时候需要指定实体类对应的表和实体类和表字段之间的对应关系等。lombok就是为了生成实体类的get\set等方法。

        <!-- Mybatis plus 依赖 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.1.0</version>
        </dependency>

       <!--lombok依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.28</version>
        </dependency>

在test数据库创建User表

create database test;
CREATE TABLE user
 (
    id 
BIGINT(20) NOT NULL COMMENT '主键ID',
    name VARCHAR(30) NULL DEFAULT NULL COMMENT 
'姓名',
    age INT(11) NULL DEFAULT NULL COMMENT '年
龄',
 PRIMARY KEY (id)
 );

在interface下创建User实体类

@TableName("user")
@Data
public class User {
    private Long id;
    private String name;
    private Integer age;
}

创建结果集

package com.zj.common;

import java.io.Serializable;

/*结果集*/
/*实现序列化因为dubbo传输的是二进制数据*/
public class CommonResult<T> implements Serializable {

private Integer code;
private String msg;
private T data;

}

创建IUserService接口

package com.zj.service;

import com.zj.common.CommonResult;
import com.zj.pojo.User;

/*用户接口*/
public interface IUserService {

    CommonResult<User> createUser(User user);
    CommonResult<User> findAllUser(User user);
    CommonResult<User> updateUser(User user);
    CommonResult<User> deleteUser(Long id);


}

(3)创建子模块user-service

这个模块就是对用户业务的具体实现,这里面的业务是需要注册到nacos上面的。

添加依赖文件

    <dependencies>

        <!--springboot依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--dubbo整合spring boot的依赖包-->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
        </dependency>

        <!--dubbo注册到nacos上的依赖包-->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-registry-nacos</artifactId>
        </dependency>


        <!-- Mybatis plus 依赖 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.7</version>
        </dependency>

        <!--MySQL 数据库依赖 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.49</version>
        </dependency>

        <!--接口的依赖-->
        <dependency>
            <groupId>com.zj</groupId>
            <artifactId>1interface</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

    </dependencies>

创建mapper层获取数据库的数据。

package com.zj.mapepr;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zj.pojo.User;

public interface UserMapper extends BaseMapper<User> {
    
}

别忘了在启动类上添加上这三个注解。

@EnableDubbo
@MapperScan("com.zj.mapper")
@SpringBootApplication
public class userService
{
    public static void main( String[] args )
    {
        SpringApplication.run(userService.class, args);
    }
}

 @EnableDubbo注解是使用Dubbo进行服务化开发的关键注解,它使得Spring Boot应用能够方便地集成和使用Dubbo框架提供的分布式服务能力。

当你将这个注解添加到你的Spring Boot应用的配置类上时,它会做以下几件事情:

  1. 开启Dubbo自动配置:它会触发Spring Boot的自动配置机制,自动配置Dubbo相关的Bean。

  2. 服务暴露:在Spring容器中,标注了@Service(注意这里不是Spring的@Service,而是Dubbo的@Service注解)的类会被识别为Dubbo服务,并且会被注册到注册中心(比如Zookeeper),从而可以被其他服务发现和调用。

  3. 服务引用:它允许你的应用通过Dubbo去引用其他服务。通常是通过@Reference注解来注入其他Dubbo服务。

  4. 配置加载:它会加载Dubbo相关的配置,这些配置可以是写在application.propertiesapplication.yml文件中,也可以是通过其他方式定义的Dubbo配置类。

  5. 依赖注入:它支持将Dubbo的Reference(服务引用)注入到Spring管理的Bean中,使得远程服务调用就像调用本地方法一样简单。

  6. 服务监控@EnableDubbo还负责集成Dubbo的监控功能,比如可以通过配置将服务的调用次数、调用时间等信息发送到监控中心。

创建service层实现IUserService接口,并将该业务注册到nacos上。

package com.zj.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.zj.common.CommonResult;
import com.zj.mapper.UserMapper;
import com.zj.pojo.User;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;


import java.util.List;

/*用户的业务层*/
@DubboService   //将该业务发布到注册中心nacos
public class UserServiceImpl implements IUserService{

    @Autowired
    private UserMapper userMapper;

    /*添加用户*/
    @Override
    public CommonResult<User> createUser(User user) {
        CommonResult<User> userCommonResult = new CommonResult<>();
        int insert = userMapper.insert(user);
        if(insert > 0){
            userCommonResult.setCode(200);  //结果的编码
            userCommonResult.setMsg("success");  //结果的描述
        }else {
            userCommonResult.setCode(500);
            userCommonResult.setMsg("fail");
        }
        return userCommonResult;
    }


    /*查询用户,这个地方不能加泛型*/
    @Override
    public CommonResult findAllUser(User user) {
        CommonResult userCommonResult = new CommonResult<>();
        //查询条件构造器
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        //id不为空的话使用id查询
        lqw.eq(user.getId() != null,User::getId,user.getId());
        //name不为空的话使用id查询
        lqw.eq(user.getName() != null,User::getName,user.getName());
        //age不为空的话使用id查询
        lqw.eq(user.getAge() != null,User::getAge,user.getAge());

        //查询用户
        List<User> users = userMapper.selectList(lqw);
        userCommonResult.setCode(200);
        userCommonResult.setMsg("success");
        userCommonResult.setData(users);
        return userCommonResult;
    }


    //更新用户
    @Override
    public CommonResult updateUser(User user) {
        CommonResult userCommonResult = new CommonResult<>();
        if(user.getId() == null){
            userCommonResult.setCode(500);
            userCommonResult.setMsg("id = null");
            return userCommonResult;
        }

        /*条件构造器*/
        LambdaUpdateWrapper<User> lqw = new LambdaUpdateWrapper<>();
        lqw.set(user.getName() != null, User::getName, user.getName())
                .set(user.getAge() != null, User::getAge, user.getAge())
                .eq(User::getId, user.getId());

        //更新
        int update = userMapper.update(null, lqw);
        if(update > 0){
            userCommonResult.setCode(200);
            userCommonResult.setMsg("success");
        }else {
            userCommonResult.setCode(500);
            userCommonResult.setMsg("fail");
        }
        return userCommonResult;
    }


    //删除
    @Override
    public CommonResult<User> deleteUser(Long idr) {
        CommonResult<User> userCommonResult = new CommonResult<>();
        if(idr == null){
            userCommonResult.setCode(500);
            userCommonResult.setMsg("id = null");
            return userCommonResult;
        }
        int i = userMapper.deleteById(idr);
        if(i > 0){
            userCommonResult.setCode(200);
            userCommonResult.setMsg("success");
        }else {
            userCommonResult.setCode(500);
            userCommonResult.setMsg("fail");
        }
        return userCommonResult;
    }

}

需要注意的是查询全部的用户的时候不能写泛型,因为查询出来的不是User而是个List。 

创建user-service模块的配置文件application.yml文件

dubbo:
  application:
#    项目名称
    name: user-service
#    通讯协议
  protocol:
    name: dubbo
#    端口号 设置端口为 -1 表示 dubbo 自动扫描并使用可用端口(从20880开始递增),避免了端口冲突的问题。
    port: -1
  registry:
#    服务的注册地址
    address: nacos://192.168.66.100:8848

server:
  port: 8001

#配置数据源
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://192.168.66.100:3306/test?serverTimezone=UTC
    username: root
    password: 123456

 (4)服务接口测试

启动user-service模块

创建测试项目,使apifox测试,选择Dubbo类型的项目。

 导入接口数据,注意导入的是nacos的数据。

(5)创建消费者模块

导入消费者模块的依赖

 <dependencies>

        <!--thymeleaf-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <!--springboot依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--dubbo整合spring boot的依赖包-->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
        </dependency>

        <!--dubbo注册到nacos上的依赖包-->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-registry-nacos</artifactId>
        </dependency>

        <!--这个不能忘记,因为在消费者模块中也就是consume中需要使用userService模块的服务-->
        <dependency>
            <groupId>com.zj</groupId>
            <artifactId>1interface</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

添加配置文件。

消费者也是需要调用nacos中的服务的因此也需要将服务注册到nacos上。因此需要添加下面的配置,除此之外还需要添加Thymeleaf的配置。

spring-boot很多配置都有默认配置,比如默认页面映射路径为:classpath:/templates/*.html

同样静态文件路径为:classpath:/static/
 

thymeleaf是前端的页面因此这里创建子模块是consume是专门消费服务的,也就是前台发请求显示页面的模块。

在consume 模块的resource目录下创建template文件夹和static文件夹。

dubbo:
  application:
    name: consume-service
  protocol:
    name: dubbo
  registry:
    address: nacos://192.168.66.100:8848
server:
  port: 8002

spring:
  thymeleaf:
    cache: false
    mode: HTML5
    encoding: utf-8
    content-type: text/html

在templates下面创建视图页面。

首页

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>

<a href="/addUser">添加用户</a>
<a href="/user/showUser">查询用户</a>

</body>
</html>

添加用户

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>添加用户</title>
</head>
<body>

<form action="/user/addUser" method="post">
    <input type="hidden" name="id" value="0">
    用户名字:<input type="text" name="name" placeholder="请输入名字">
    用户年龄:<input type="text" name="age" placeholder="请输入年龄">
    <input type="submit" value="添加用户">
</form>

</body>
</html>>

OK页面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<link rel="shortcut icon" href="../resources/favicon.ico" th:href="@{/static/favicon.ico}"/>
<head>
    <meta charset="UTF-8">
    <title>成功页面</title>
</head>
<body>
操作成功请<a href="/index">返回</a>
</body>
</html>

error页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
执行失败<a href="/index">返回</a>
</body>
</html>

显示用户信息

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>查询用户</title>
</head>
<body>

<table>
    <tr>
        <td>序号</td>
        <td>名字</td>
        <td>用户年龄</td>
        <td>操作</td>
    </tr>
    <tr th:each="u : ${users}">
        <td th:text="${u.id}"></td>
        <td th:text="${u.name}"></td>
        <td th:text="${u.age}"></td>
        <td>
            <a th:href="@{/user/delete(id=${u.id})}">删除</a>
            <a th:href="@{/user/toUpdate(id=${u.id})}">更新</a>
        </td>
    </tr>
</table>


</body>
</html>

更新用户页面。

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>更新用户</title>
</head>
<body>


<form action="/user/update" method="post">
    <input type="hidden" name="id" th:value="${user.id}">
    用户名字:<input type="text" name="name" placeholder="请输入名字" th:value="${user.name}">
    用户年龄:<input type="text" name="age" placeholder="请输入年龄" th:value="${user.age}">
    <input type="submit" value="更新用户">
</form>
</body>
</html>

然后创建两个controller,一个负责页面跳转的。

package com.zj.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.ResponseBody;

/*视图层控制器*/
@Controller
public class IndexController {

    /*页面跳转*/
    @GetMapping("/{page}")
    public String index(@PathVariable String page) {
        return page;
    }
    
    /*忽略favicon*/
    @GetMapping("favicon.ico")
    @ResponseBody
    void noFavicon() {
    }

}

 一个负责处理具体的业务请求的。

package com.zj.controller;


import com.zj.common.CommonResult;
import com.zj.pojo.User;
import com.zj.service.IUserService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import java.util.List;


@Controller
@RequestMapping("/user")
public class UserController {

    //远程调用添加用户的操作,添加用户的服务是user-service模块提供的,需要注意的是要引入interface模块依赖
    @DubboReference
    private IUserService userService;

    /*添加用户*/
    @PostMapping("/addUser")
    public String addUser(User user){
        CommonResult<User> result = userService.createUser(user);
        //判断是不是添加成功
        if (result.getCode() == 200){
            return "redirect:/ok";
        }else {
            return "redirect:/error";
        }
    }

    /*查询用户*/
    @GetMapping("/showUser")
    public ModelAndView selectUser(){
        //既要返回视图还需要返回结果
        ModelAndView modelAndView = new ModelAndView();
        User user1 = new User();
        CommonResult<User> allUser = userService.findAllUser(user1);
        //视图添加数据
        modelAndView.addObject("users",allUser.getData());
        //返回视图
        modelAndView.setViewName("showUser");
        return modelAndView;
    }

    /*根据id查询数据跳转到更新数据的页面*/
    @GetMapping("/toUpdate")
    public ModelAndView toUpdateUser(Long id){
        ModelAndView modelAndView = new ModelAndView();
        User user = new User();
        user.setId(id);
        CommonResult allUser = userService.findAllUser(user);
        List<User> data = (List<User>)allUser.getData();
        if (data.size() > 0){
           modelAndView.addObject("user",data.get(0));  //取出第一个数据
             modelAndView.setViewName("update");
        }
        return modelAndView;
    }

    /*更新用户*/
    @PostMapping("/update")
    public String updateUser(User user){
        System.out.println("user:"+user);
        CommonResult<User> userCommonResult = userService.updateUser(user);
        if (userCommonResult.getCode() == 200){
            return "redirect:/ok";
        }else{
            return "redirect:/error";
        }
    }

    /*删除用户*/
    @GetMapping("/delete")
    public String deleteUser(Long id){
        CommonResult<User> userCommonResult = userService.deleteUser(id);
        if (userCommonResult.getCode() == 200){
            return "redirect:/ok";
        }else {
            return "redirect:/error";
        }
    }
}

需要注意的就是这个@DubboReference注解,就是获取nacos的服务实例,注入到userService变量中。

另外根据id查询用户的时候需要注意的是查询结果是个List所以取出第一个来。

最后启动类加注解。

/*告诉 Spring Boot 不要自动配置数据源。使用我配置的数据源。*/
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@EnableDubbo
public class userConsume
{
    public static void main( String[] args )
    {
        SpringApplication.run(userConsume.class, args);
    }
}

 @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})第一次碰到这个注解,不叫的话会出错。

最后是配置文件。

dubbo:
  application:
    name: consume-service
  protocol:
    name: dubbo
  registry:
    address: nacos://192.168.66.100:8848
server:
  port: 8002


#配置视图
spring:
  thymeleaf:
    cache: false
    mode: HTML5
    encoding: utf-8
    content-type: text/html

最后启动user-service模块和user-consum模块,在浏览器输入locahost:8082/index就行啦。

详细的项目代码已经上传。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

“AI智能安全管理系统:让安全无处不在

嘿&#xff0c;大家好&#xff01;今天咱们来聊聊一个超级酷炫又至关重要的东西——AI智能安全管理系统。想象一下&#xff0c;如果有一个系统可以像私人保镖一样24小时不间断地保护你和你的财产&#xff0c;是不是感觉特别安心&#xff1f;这就是AI智能安全管理系统带给我们的…

【hackmyvm】soul靶机wp

tags: HMVrbash绕过图片隐写PHP配置解析 1. 基本信息^toc 文章目录 1. 基本信息^toc2. 信息收集3. 图片解密3.1. 爆破用户名3.2. 绕过rbash3.3. 提权检测 4. 获取webshell4.1. 修改php配置 5. www-data提权gabriel6. gabriel提取到Peter7. Peter提权root 靶机链接 https://ha…

PaddleOCR训练自己的私有数据集(包括标注、制作数据集、训练及应用)

目录 一、制作数据集 1、进入到PaddleOCR-releas-2.7目录 2、首先启用PPOCRLabel&#xff1a;在终端激活环境 3、接着点击左下角的自动标注 4、确认完成后点击左上角 5、新建gen_ocr_train_val_test.py 二、训练文字检测模型 1、模型下载 2.、配置ppocr检测模型文件 …

网络层协议--ip协议

目录 引言 IP协议 协议头格式 16位标识与3位标志与13位片偏移讲解 网段划分(重要) DHCP技术 CIDR技术 特殊的IP地址 广播主机 IP地址的数量限制 私有IP地址和公网IP地址 路由&#xff1a;在复杂的网络结构中, 找出一条通往终点的路线 简单认识路由器 路由表生成算…

区块链期末复习3.2:比特币脚本

目录 一、输入输出脚本的执行 二、简单脚本实例及压栈过程 1.P2PK&#xff08;pay to public key hash&#xff09; 2、P2PH&#xff08;pay to public key hash&#xff09; 3.多重签名 4.比特币脚本的应用&#xff1a; 三、其他常见指令 1.OP_EQUAL与OP&#xff3f;EQ…

【Mac】终端改色-让用户名和主机名有颜色

效果图 配置zsh 1.打开终端&#xff0c;进入.zshrc配置 cd ~ vim .zshrc2.添加如下配置并保存 # 启用命令行颜色显示 export CLICOLOR1 ## 加载颜色支持 autoload -U colors && colors # 配置 zsh 提示符 PROMPT"%{$fg_bold[red]%}%n%{$reset_color%}%{$fg_bol…

CUDA各种内存和使用方法

文章目录 1、全局内存2、局部内存3、共享内存3.1 静态共享内存3.2 动态共享内存 4、纹理内存5、常量内存6、寄存器内存7、用CUDA运行时API函数查询设备CUDA 错误检测 1、全局内存 特点&#xff1a;容量最大&#xff0c;访问延时最大&#xff0c;所有线程都可以访问。 线性内存…

青少年科普教学系统平台的设计与实现springboot

摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对高校教师成果信息管理混乱&#xff0c;出错率高&#xff0c;信息安…

Vue2:v-for创建echart图表时不能使用动态ref,要使用动态id

项目中需要创建一组图表+表格的组合,一共15组,为了便于维护,希望使用v-for来创建,而不是写出15组<div>,但是动态指定echart的ref时,频繁遭遇init失败,提示“TypeError: this.dom.getContext is not a function”。过程记录如下。 实现效果 要实现的效果如下图,…

Ch9 形态学图像处理

Ch9 形态学图像处理 blog点此处&#xff01;<--------- 四大算子相应性质。 腐蚀、膨胀、开闭之间的含义、关系 文章目录 Ch9 形态学图像处理预备知识(Preliminaries)膨胀和腐蚀(Dilation and Erosion)腐蚀膨胀膨胀与腐蚀的对偶关系 开闭操作(Opening and Closing)开运算闭…

likeAdmin架构部署(踩坑后的部署流程

1、gitee下载 https://gitee.com/likeadmin/likeadmin_java.git 自己克隆 2、项目注意 Maven&#xff1a;>3.8 ❤️.9 (最好不要3.9已经试过失败 node &#xff1a;node14 (不能是18 已经测试过包打不上去使用14的换源即可 JDK&#xff1a;JDK8 node 需要换源 npm c…

如何解决 ‘adb‘ 不是内部或外部命令,也不是可运行的程序或批处理文件的问题

在cmd中输入 adb &#xff0c;显示 ‘adc‘ 不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件的问题 解决办法&#xff1a;在环境变量中添加adb所在的路径 1、找到 adb.exe 的所在的文件路径&#xff0c;一般在 Android 安装目录下 \sdk\platform-tools\adb.exe…

使用 OpenCV 在图像中添加文字

在图像处理任务中&#xff0c;我们经常需要将文本添加到图像中。OpenCV 提供了 cv2.putText() 函数&#xff0c;可以很方便地在图像上绘制文本&#xff0c;支持多种字体、颜色、大小和位置等参数。 本文将详细介绍如何使用 OpenCV 在图像中添加文字&#xff0c;介绍 cv2.putTe…

解线性方程组

直接三角分解&#xff08;LU分解&#xff0c;Doolittle分解&#xff09; ATM分解&#xff08;追赶法&#xff0c;Crout分解&#xff0c;克劳特分解&#xff09; 平方根法&#xff08;Cholesky分解&#xff0c;乔列斯基分解&#xff09; 矩阵的范数

17.2、应急事件场景与处理流程

目录 常见网络安全应急事件场景网络安全应急处理流程应急演练类型 常见网络安全应急事件场景 应急事件的处理场景&#xff0c;分成四类场景&#xff0c;恶意程序事件&#xff0c;网络攻击事件&#xff0c;还有网站相关的一些安全事件&#xff0c;最后是拒绝服务事件 恶意程序…

并发编程 - 死锁的产生、排查与解决方案

在多线程编程中&#xff0c;死锁是一种非常常见的问题&#xff0c;稍不留神可能就会产生死锁&#xff0c;今天就和大家分享死锁产生的原因&#xff0c;如何排查&#xff0c;以及解决办法。 线程死锁通常是因为两个或两个以上线程在资源争夺中&#xff0c;形成循环等待&#xf…

关于埃斯顿机器人文件导出或者系统日志导出

关于埃斯顿机器人文件导出或者日志导出&#xff0c;登录模式&#xff0c;选择高级设置&#xff0c;控制器备份恢复 选择U盘导入地址&#xff0c;点击导出&#xff0c;等待时间30秒就可以查看文件格式和系统日志

5G CPE接口扩展之轻量型多口千兆路由器小板选型

多口千兆路由器小板选型 方案一: 集成式5口千兆WIFI路由器小板方案二:交换板 + USBwifiUSB WIFI选型一USBwifi选型二:四口千兆选型一四口千兆选型二:四口千兆选型三:部分5G CPE主板不支持Wifi,并且网口数量较少,可采用堆叠方式进行网口和wifi功能 扩展,本文推荐一些路由…

PromptGIP:Unifying lmage Processing as Visual Prompting Question Answering

“Unifying Image Processing as Visual Prompting Question Answering” 文章提出了一种名为 PromptGIP 的通用模型&#xff0c;将图像处理任务统一为视觉提示问答范式&#xff0c;在多个图像处理任务上展现出良好性能&#xff0c;为通用图像处理提供了新的思路和方法。 confe…

【MySQL】索引 面试题

文章目录 适合创建索引的情况创建索引的注意事项MySQL中不适合创建索引的情况索引失效的常见情况 索引定义与作用 索引是帮助MySQL高效获取数据的有序数据结构&#xff0c;通过维护特定查找算法的数据结构&#xff08;如B树&#xff09;&#xff0c;以某种方式引用数据&#xf…