分散式遠程調用SpringCloud-Feign的兩種具體操作方式(精華)

来源:https://www.cnblogs.com/ccz-love-lqm/archive/2019/12/03/11977698.html
-Advertisement-
Play Games

一 前言 幾大RPC框架介紹 1.支持多語言的RPC框架,google的gRPC,Apache(facebook)的Thrift 2.只支持特定語言的RPC框架,例如新浪的Motan 3.支持服務治理等服務化特性的分散式框架,例如阿裡的dubbo 4.擁有完整生態的spring cloud spri ...


一 前言

幾大RPC框架介紹

1.支持多語言的RPC框架,google的gRPC,Apache(facebook)的Thrift 2.只支持特定語言的RPC框架,例如新浪的Motan 3.支持服務治理等服務化特性的分散式框架,例如阿裡的dubbo 4.擁有完整生態的spring cloud  

spring cloud遠程調用方式---Feign

Feign是一個聲明似的web服務客戶端,它使得編寫web服務客戶端變得更加容易。使用Fegin創建一個介面並對它進行註解。它具有可插拔的註解支持包括Feign註解與JAX-RS註解,Feign還支持可插拔的編碼器與解碼器,Spring Cloud 增加了對 Spring MVC的註解,Spring Web 預設使用了HttpMessageConverters, Spring Cloud 集成 Ribbon 和 Eureka 提供的負載均衡的HTTP客戶端 Feign。

Feign提供了HTTP請求的模板,通過編寫簡單的介面和插入註解,就可以定義好HTTP請求的參數、格式、地址等信息。而Feign則會完全代理HTTP請求,我們只需要像調用方法一樣調用它就可以完成服務請求及相關處理。SpringCloud對Feign進行了封裝,使其支持SpringMVC標準註解和HttpMessageConverters。Feign可以與Eureka和Ribbon組合使用以支持負載均衡。

 

官方解釋: Feign is a Java to HTTP client binder inspired by RetrofitJAXRS-2.0, and WebSocket. Feign's first goal was reducing the complexity of binding Denominator uniformly to HTTP APIs regardless of ReSTfulness.

 

Feign的兩種調用方式

1 直接在調用者聲明Feign客戶端

如下圖所示, service-b 聲明一個介面, 去調用路徑為 /user/get 的服務 service-a 的服務

 

2 在被調用者介面Api中聲明Feign客戶端

如下圖, 在被調用者中聲明介面, 去調用自己, 這種方法遵循面向介面編程, 而且使用起來, 就類似dubbo一樣, @Autowire直接註入就可以使用了.

 

以上可能看得讀者一頭霧水, 以下具體的代碼流程, 可以方便更加具體的瞭解

 

二 案例1直接在調用者聲明Feign客戶端代碼實現

以下步驟為手把手教學, 請明白我的良苦用心

步驟0 創建一個SpringCloud-Eureka註冊中心

首先創建一個父項目

把其他都刪除, 剩下pom文件

 

以下為父項目的依賴

<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <groupId>com.fegin</groupId>
    <artifactId>test</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <packaging>pom</packaging>

    <!--springboot version 2.1.4-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>


    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR1</spring-cloud.version>
    </properties>

    <!--springcloud version Greenwish.SR1-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

</project>

 

創建eureka項目

 

項目結構如圖

 

添加eureka的依賴

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <parent>
        <artifactId>test</artifactId>
        <groupId>com.fegin</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>eureka</artifactId>

    <!--eureka服務端配置-->
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>
</project>

 

添加application.yml

server:
  port: 8761

eureka:
  instance:
    hostname: localhost
  client:
    # 是否把自己作為服務註冊到其他服務註冊中心
    registerWithEureka: false
    # 是否從其他的服務中心同步服務列表
    fetchRegistry: false
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
  server:
    # 關閉保護機制,預設true
    enable-self-preservation: false
    # 剔除失效服務間隔,預設60000
    eviction-interval-timer-in-ms: 3000

 

添加啟動類代碼EurekaApplication

/**
 * @author c-can-z
 */
@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaApplication.class,args);
    }

}

 

瀏覽器輸入 http://localhost:8761/

 

步驟1 準備一個服務servicea --- 該服務為被調用者

創建一個普通springboot服務, 服務名稱為 service-a 在該服務上, 創建一個埠, 該埠為:9992 訪問該路徑: http://localhost:9991/user/get?id=5 返回為: 恭喜5號, 18歲的美美小姐    

步驟2 準備一個服務serviceb --- 該服務為調用者

創建一個serviceb

 

添加一下serviceb必須的依賴

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <parent>
        <artifactId>test</artifactId>
        <groupId>com.fegin</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>serviceb</artifactId>

    <dependencies>
        <!--springboot web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--springboot 測試-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!--eureka客戶端配置-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>
        <!--微服務調用-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

        <!--zipkin客戶端配置, 已經包含sleuth-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zipkin</artifactId>
        </dependency>
    </dependencies>

</project>

 

把 application.properties 修改為 application.yml, 本服務名稱為 service-b 埠為 9992

server:
  port: 9992
spring:
  application:
    name: service-b
  zipkin:
    base-url: http://localhost:9411
  sleuth:
    sampler:
      probability: 1
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
    registry-fetch-interval-seconds: 5 #eureka client刷新本地緩存時間,預設30
  instance:
    prefer-ip-address: true
    #Eureka客戶端向服務端發送心跳的時間間隔,單位為秒(客戶端告訴服務端自己會按照該規則),預設30
    lease-renewal-interval-in-seconds: 5
    #Eureka服務端在收到最後一次心跳之後等待的時間上限,單位為秒,超過則剔除(客戶端告訴服務端按照此規則等待自己),預設90
    lease-expiration-duration-in-seconds: 7
feign:
  client:
    config:
      default:
        connectTimeout: 7000
        readTimeout: 7000
service-b:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
logging:
  level:
    root: info

 

導入啟動類文件

@SpringBootApplication
@EnableFeignClients
public class SeriveBApplication {

    public static void main(String[] args) {
        SpringApplication.run(SeriveBApplication.class,args);
    }

}

 

創建Feign客戶端

//在創建該步驟的時候, 需要關註一下步驟1的說明
//@FeignClient(name = "service-a")註解來綁定該介面對應servic-a服務
@FeignClient(name = "service-a")
public interface UserFeginClient {
    //service-a服務對應資源路徑.必須加上@RequestParam, 否則會報錯,返回參數也必須對應上
    @RequestMapping("user/get")
    String get(@RequestParam("id")Long id);
}

 

在controller中直接進行調用

@RestController
@RequestMapping("/product")
public class ProductController {

    @Autowired
    private UserFeginClient userFeginClient;

    @RequestMapping("/get")
    public String get(Long id){
        return "產品服務抽獎: "+userFeginClient.get(id);
    }
}

 

步驟3 測試Feign調用效果

http://localhost:9992/product/get?id=5   到此, 是Fegin最簡單的用法   相信如果按照我步驟一步一步做的同學, 應該可以理解什麼是: service-b 聲明一個介面, 去調用路徑為 /user/get 的服務 service-a 的服務  

三 案例2 在被調用者介面Api中聲明Feign客戶端代碼實現

步驟1 創建servicecapi, 該Api用來創建Feign客戶端

可以在以上的項目上進行改造 項目結構   serviceapi依賴
<?xml version="1.0" encoding="UTF-8"?>
<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">
    <parent>
        <artifactId>test</artifactId>
        <groupId>com.fegin</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>servicec-api</artifactId>

    <dependencies>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <!--微服務調用-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
    </dependencies>
</project>

 

實體類product

public class Product implements Serializable {
    private Long id;
    private String name;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

 

feign客戶端

/**
 * 服務名稱
 * @author c-can-z
 */
@FeignClient(name="service-c")
public interface ProductFeignApi {

    //動態代理需要的地址, 但是我們實際操作不到
    @RequestMapping("/servicec/get")
    Product get(@RequestParam("id") Long id);
}

 

步驟2 創建servicec服務

項目結構

 

 

service項目依賴

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <parent>
        <artifactId>test</artifactId>
        <groupId>com.fegin</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>servicec</artifactId>
    <dependencies>
        <!--springboot web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--eureka客戶端配置-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <!--zipkin客戶端配置, 已經包含sleuth-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zipkin</artifactId>
        </dependency>

        <!--springboot 測試-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--導入api-->
        <dependency>
            <groupId>com.fegin</groupId>
            <artifactId>servicec-api</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

 

servicec的 application.yml

server:
  port: 9993
spring:
  application:
    name: service-c
  zipkin:
    base-url: http://localhost:9411
  sleuth:
    sampler:
      probability: 1
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
    registry-fetch-interval-seconds: 5 #eureka client刷新本地緩存時間,預設30
  instance:
    prefer-ip-address: true
    #Eureka客戶端向服務端發送心跳的時間間隔,單位為秒(客戶端告訴服務端自己會按照該規則),預設30
    lease-renewal-interval-in-seconds: 5
    #Eureka服務端在收到最後一次心跳之後等待的時間上限,單位為秒,超過則剔除(客戶端告訴服務端按照此規則等待自己),預設90
    lease-expiration-duration-in-seconds: 7
feign:
  client:
    config:
      default:
        connectTimeout: 7000
        readTimeout: 7000
logging:
  level:
    root: info

 

實現Feign客戶端介面, 也是該文章的核心代碼

採用實現的方式

/**
 * 遠程調用介面的實現類
 * @author c-can-z
 */
@RestController
public class ProductFeignClient implements ProductFeignApi {

    @Override
    public Product get(Long id) {
        Product product = new Product();
        product.setId(id);
        product.setName("我是服務C");
        return product;
    }
}

 

servicec的啟動類

@SpringBootApplication
public class ProductServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProductServerApplication.class, args);
    }
}

 

步驟3 創建serviced服務去調用servicec

項目結構

註意啟動類的位置, servicecapi的路徑必須被啟動類掃描到

 

serviced的依賴, 

註意, 必須引入servicec的api, 有人會說有代碼侵入的問題, 但是對比案例1, 如果多個項目調用, 要創建多個Feign客戶端, 孰是孰非, 還得看項目的具體需求

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <parent>
        <artifactId>test</artifactId>
        <groupId>com.fegin</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>serviced</artifactId>

    <dependencies>
        <!--springboot web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--springboot 測試-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!--eureka客戶端配置-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!--微服務調用-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!--zipkin客戶端配置, 已經包含sleuth-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zipkin</artifactId>
        </dependency>

        <dependency>
            <groupId>com.fegin</groupId>
            <artifactId>servicec-api</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>

 

serviced的 application.yml

server:
  port: 9994
spring:
  application:
    name: service-d
  zipkin:
    base-url: http://localhost:9411
  sleuth:
    sampler:
      probability: 1
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
    registry-fetch-interval-seconds: 5 #eureka client刷新本地緩存時間,預設30
  instance:
    prefer-ip-address: true
    #Eureka客戶端向服務端發送心跳的時間間隔,單位為秒(客戶端告訴服務端自己會按照該規則),預設30
    lease-renewal-interval-in-seconds: 5
    #Eureka服務端在收到最後一次心跳之後等待的時間上限,單位為秒,超過則剔除(客戶端告訴服務端按照此規則等待自己),預設90
    lease-expiration-duration-in-seconds: 7
feign:
  client:
    config:
      default:
        connectTimeout: 7000
        readTimeout: 7000
logging:
  level:
    root: info

 

serviced的控制類

/**
 * @author c-can-z
 */
@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    private ProductFeignApi productFeignApi;

    @RequestMapping("/get")
    public String get(Long id){
        Product product = productFeignApi.get(id);
        return "訂單為: 貨品:" + product.getName() + ", 貨品id:"+product.getId();
    }
}

 

serviced的啟動類

/**
 * @author c-can-z
 */
@SpringBootApplication
@EnableFeignClients
public class ServiceDApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceDApplication.class,args);
    }
}

 

步驟4 測試Feign調用效果

http://localhost:9994/order/get?id=5

 

四 總結

到了這裡, 不知道你是否理解 直接在調用者聲明Feign客戶端 或者 在被調用者介面Api中聲明Feign客戶端

直接在調用者聲明Feign客戶端:

每一個服務調用其他服務, 就需要創建一個客戶端, 從代碼方面來說, 相對比較麻煩

在被調用者介面Api中聲明Feign客戶端:

從調用者來看, 使用起來就跟使用淘寶的dubbo一樣方便, 但是每一個服務調用其他服務,

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 該問題可能導致tomcat啟動成功了,但是瀏覽器輸入http://127.0.0.1:8080無法顯示tomcat的歡迎界面 打開Tomcat安裝目錄下的bin文件下的setclasspath.sh,在文檔開頭添加如下語句: export JAVA_HOME=你的jdk路徑 export JRE_H ...
  • Linux 命令之 scp 命令詳解 一、scp 簡介 scp 命令用於不同主機之間複製文件和目錄。 scp 是 secure copy 的縮寫,是 基於 ssh 協議進行安全的遠程文件拷貝命令。 scp 想要免密進行複製,需要發送秘鑰給相應的節點。 scp 是加密的,rcp 是不加密的,scp 是 ...
  • KubeSphere 不僅支持部署在 Linux 之上,還支持在已有 Kubernetes 集群之上部署 KubeSphere,自動納管 Kubernetes 集群的已有資源與容器。 前提條件 版本: Helm = 2.10.0`(不支持 helm 2.16.0 " 6894" ),且已安裝了 Ti ...
  • CentOS 7 下安裝部署java+tomcat+mysql 前置:CentOS7安裝:https://jingyan.baidu.com/article/b7001fe1d1d8380e7382dd72.html 附常用命令合集:https://www.cnblogs.com/icebutter ...
  • 今天,下午刷手機的時候,突然看到kali出了一個非常新穎的主題;該主題可以使得kali系統偽裝成windows 10而變得低調起來;就像下麵這樣: 具體新聞鏈接:https://www.freebuf.com/news/221582.html Kali Undercover模式 如果你在某些環境中想 ...
  • 最近需要使用 kali 源安裝一些軟體: 配置 sources.list,根據如下鏈接:http://mirrors.ustc.edu.cn/help/kali.html 獲取 公鑰;apt-key adv --keyserver keyserver.ubuntu.com --recv ED444F ...
  • 前言 上周四,伺服器突然掛了。SSH都連接不上,日常的小程式後臺直接down掉,小程式每日大概3K左右訪問量。於是乎就開啟了,排查之後。 排查階段 什麼先別說,先把服務恢復再說。重啟阿裡雲伺服器,SSH連接。開啟nginx,redis,mysql,java服務。一系列操作,先把服務先啟動了。 伺服器 ...
  • 一 Kubernetes DNS介紹1.1 Kubernetes DNS發展作為服務發現機制的基本功能,在集群內需要能夠通過服務名對服務進行訪問,因此需要一個集群範圍內的DNS服務來完成從服務名到ClusterIP的解析。DNS服務在Kubernetes的發展過程中經歷了3個階段,SkyDNS --... ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...