明解Spring6(一)------邂逅

来源:https://www.cnblogs.com/hanyu-2020/archive/2023/02/01/17081313.html
-Advertisement-
Play Games

一、Spring簡介 1、Spring介紹 Spring 是一款主流的 Java EE 輕量級開源框架 ,Spring 由“Spring 之父”Rod Johnson 提出並創立,其目的是用於簡化 Java 企業級應用的開發難度和開發周期。Spring的用途不僅限於伺服器端的開發。從簡單性、可測試性 ...


一、Spring簡介

1、Spring介紹

Spring 是一款主流的 Java EE 輕量級開源框架 ,Spring 由“Spring 之父”Rod Johnson 提出並創立,其目的是用於簡化 Java 企業級應用的開發難度和開發周期。Spring的用途不僅限於伺服器端的開發。從簡單性、可測試性和松耦合的角度而言,任何Java應用都可以從Spring中受益。Spring 框架除了自己提供功能外,還提供整合其他技術和框架的能力。

Spring 自誕生以來備受青睞,一直被廣大開發人員作為 Java 企業級應用程式開發的首選。時至今日,Spring 儼然成為了 Java EE 代名詞,成為了構建 Java EE 應用的事實標準。

官網:https://spring.io/

2、使用Spring的原因

官方解釋:https://spring.io/why-spring

Spring使Java編程對每個人來說更快、更容易、更安全。 Spring對速度、簡單性和生產率的關註使它成為世界上最流行的Java框架。 spring給整個行業帶來等了春天,為我們軟體的開髮帶來了極大的便利。

參考:snyk發佈的2021年JVM 生態系統報告(2022年的還沒有發佈)

image.png

Java 世界仍然是 Spring 主導的世界,超過一半的市場使用 Spring Boot,幾乎三分之一使用 Spring MVC。總的來說,我們看到我們生活在一個高度由 Spring 主導的宇宙中,這似乎表明 Spring 的人們在為社區服務方面做得很好。

  • Spring is everywhere

Spring 框架提供靈活的類庫受到世界各地開發人員的信任。無論是流媒體電視、線上購物、還是無數其他創新的解決方案,Spring每天都為數百萬終端用戶提供愉快的體驗。Spring也有來自所有科技巨頭的貢獻,包括阿裡巴巴、亞馬遜、谷歌、微軟等。

  • Spring is flexible

Spring 靈活而全面的擴展能力和第三方庫讓開發人員可以構建幾乎任何可以想象到的應用程式。 Spring框架的控制反轉(IoC)和依賴註入(DI)特性為一系列廣泛的特性和功能提供了基礎。 無論您是在為web構建安全的、響應式的、基於雲的微服務,還是為企業構建複雜的流數據流,Spring都有工具可以提供幫助。

  • Spring is productive

Spring Boot 改變了您處理Java編程任務的方式,從根本上簡化了您的體驗。 Spring Boot結合了應用程式上下文和自動配置的嵌入式web伺服器等必要條件,使microservice開發變得輕而易舉。 為了更快,您可以將Spring Boot與Spring Cloud豐富的支持庫、伺服器、模式和模板組合在一起,以創紀錄的時間將整個基於微服務的架構安全地部署到雲中。

  • Spring is fast

我們的工程師非常關心性能。 在Spring中,預設情況下,您會註意到快速啟動、快速關閉和優化執行。 Spring項目也越來越多地支持reactive(nonblocking)編程模型,以獲得更高的效率。 開發人員的生產力是Spring的超級力量。 Spring Boot幫助開發人員輕鬆地構建應用程式,而且比其他競爭範式要輕鬆得多。

  • Spring is secure

Spring在處理安全問題方面十分可靠。 Spring代碼的貢獻者與安全專業人員一起修補和測試任何報告的漏洞。 第三方依賴關係也被密切監控,並定期發佈更新,以幫助您的數據和應用程式儘可能安全。 此外,Spring Security使您更容易集成行業標準的安全方案,並交付可靠的預設安全解決方案。

  • Spring is supportive

Spring社區是一個龐大的、全球性的、多樣化的社區,涵蓋了所有年齡和能力的人,從完全的初學者到經驗豐富的專業人士。 無論你處在人生的哪個階段,你都能找到幫助你進入下一個階段的支持和資源。

3、Spring提供的功能

image.png

總結:Spring發展到現在已經不再是一個單純的應用框架,而是逐漸發展成為一個由多個不同子項目(模塊)組成的成熟技術,例如 Spring Framework、SpringBoot、Spring Cloud、Spring Data、Spring Security 等。

Spring提供的所有項目組成:https://spring.io/projects

這些子項目涵蓋了從企業級應用開發到雲計算等各方面的內容,能夠幫助開發人員解決軟體發展過程中不斷產生的各種實際問題,給開發人員帶來了更好的開發體驗。

Spring Framework 是其它子項目的基礎,可以理解成 Spring 的項目也只是在 Spring Framework 的基礎上對其進行擴展實現的。故我們也稱 Spring Framework 為 Spring 框架。框架本身的好處是重用性,其它項目不用重覆開發Spring Framework已經實現的功能,對其添磚加瓦,形成自己特色的項目就好。

而且我們所說的Spring MVC其實也屬於Spring Framework核心項目之一;只是因為使用頻率最高且強調web功能,所以我們會拆出來成為Spring MVC 框架。

4、Spring Framework組成

官網介紹:https://spring.io/projects/spring-framework#overview

image.png

image.png

上圖中包含了 Spring 框架的所有模塊,這些模塊可以滿足一切企業級應用開發的需求,在開發過程中可以根據需求有選擇性地使用所需要的模塊。下麵分別對這些模塊的作用進行簡單介紹。

  1. Spring Core(核心容器)

spring core提供了IOC,DI,Bean配置裝載創建的核心實現。核心概念: Beans、BeanFactory、、ApplicationContext。

  • spring-core :IOC和DI的基本實現
  • spring-beans:BeanFactory和Bean的裝配管理(BeanFactory)
  • spring-context:Spring context上下文,即IOC容器(AppliactionContext)
  • spring-expression:spring表達式語言
  1. Spring AOP
  • spring-aop:面向切麵編程的應用模塊,整合ASM,CGLib,JDK Proxy
  • spring-aspects:集成AspectJ,AOP應用框架
  • spring-instrument:動態Class Loading模塊
  1. Spring Data Access
  • spring-jdbc:spring對JDBC的封裝,用於簡化jdbc操作
  • spring-orm:java對象與資料庫數據的映射框架
  • spring-oxm:對象與xml文件的映射框架
  • spring-jms: Spring對Java Message Service(java消息服務)的封裝,用於服務之間相互通信
  • spring-tx:spring jdbc事務管理
  1. Spring Web
  • spring-web:最基礎的web支持,建立於spring-context之上,通過servlet或listener來初始化IOC容器
  • spring-webmvc:實現web mvc
  • spring-websocket:與前端的全雙工通信協議
  • spring-webflux:Spring 5.0提供的,用於取代傳統java servlet,非阻塞式Reactive Web框架,非同步,非阻塞,事件驅動的服務,Netty,Undertow和Servlet 3.1+容器等伺服器上運行
  1. Spring Message
  • Spring-messaging:spring 4.0提供的,為Spring集成一些基礎的報文傳送服務
  1. Spring test
  • spring-test:集成測試支持,主要是對junit的封裝

5、Spring Framework特點

  • 非侵入式:使用 Spring Framework 開發應用程式時,Spring 對應用程式本身的結構影響非常小。對領域模型可以做到零污染;對功能性組件也只需要使用幾個簡單的註解進行標記,完全不會破壞原有結構,反而能將組件結構進一步簡化。這就使得基於 Spring Framework 開發應用程式時結構清晰、簡潔優雅。
  • 控制反轉:IoC——Inversion of Control,翻轉資源獲取方向。把自己創建資源、向環境索取資源變成環境將資源準備好,我們享受資源註入。
  • 面向切麵編程:AOP——Aspect Oriented Programming,在不修改源代碼的基礎上增強代碼功能。
  • 容器:Spring IoC 是一個容器,因為它包含並且管理組件對象的生命周期。組件享受到了容器化的管理,替程式員屏蔽了組件創建過程中的大量細節,極大的降低了使用門檻,大幅度提高了開發效率。
  • 組件化:Spring 實現了使用簡單的組件配置組合成一個複雜的應用。在 Spring 中可以使用 XML 和 Java 註解組合這些對象。這使得我們可以基於一個個功能明確、邊界清晰的組件有條不紊的搭建超大型複雜應用系統。
  • 一站式:在 IoC 和 AOP 的基礎上可以整合各種企業應用的開源框架和優秀的第三方類庫。而且 Spring 旗下的項目已經覆蓋了廣泛領域,很多方面的功能性需求可以在 Spring Framework 的基礎上全部使用 Spring 來實現。

Spring框架版本:Spring6要求JDK最低版本是JDK17

二、IoC概述

1、背景介紹

介紹IOC之前我們先對其背景進行介紹,也即對象的創建史!

1) 普通new實例

在實際項目設計過程中,介面是一個重要組成元素,不同層之間的操作需要通過介面來調用。利用介面,可以實現子類的隱藏,也可以更好地描述不同層之間的操作標準。Java中要想獲得介面對象,需要通過關鍵字new來實現。下麵的案例不要研究其業務意義,只是一個測試demo!

public interface ConnectionMessage {
    public String select();
}
public class MySQLMessageImpl implements ConnectionMessage {
    @Override
    public String select() {
        System.out.println("連接---查詢MySQL資料庫信息");
        return "";
    }
}
public class MyTest {
    public static void main(String[] args) {
        ConnectionMessage message = new MySQLMessageImpl();
        message.select();
    }
}

16751582110323012285ffy

以上是使用MySQL操作的模擬程式,如果切換為PostgreSQL就需要修改其使用類!

public class MyTest {
    public static void main(String[] args) {
        //ConnectionMessage message = new MySQLMessageImpl();
        ConnectionMessage message = new PostgreSQLMessageImpl();
        message.select();
    }
}

16751582110323010116ffy

這就是所謂的耦合,調用的時候要修改代碼,即直接new , 顯然不符合面向對象的設計原則---------開閉原則

2.1)普通工廠

針對上面的情況我們可以使用工廠方式,創建一個BeanFactory.java文件

public class BeanFactory {
    public static ConnectionMessage select(){
        return new MySQLMessageImpl();
    }
}

這樣使用的時候就變成下麵這樣

public class MyTest {
    public static void main(String[] args) {
//        ConnectionMessage message = new MySQLMessageImpl();
//        ConnectionMessage message = new PostgreSQLMessageImpl();
        ConnectionMessage message = BeanFactory.select();
        message.select();
    }
}

16751582110323019638ffy

上圖的思想沒問題,但是我們的代碼還尚有問題,即BeanFactory裡面還是有代碼耦合

image.png

2.2)反射工廠1.0

我們接下來可以利用反射完善一下!

public class BeanFactory {
    private static ConnectionMessage message;
    public static ConnectionMessage select() throws Exception {
        Class<?> clazz = Class.forName("com.ty.demo.dao.impl.MySQLMessageImpl");
        message = (MySQLMessageImpl) clazz.getDeclaredConstructor().newInstance();
        return message;
    }
}

這樣比直接new好多了,減少了工廠內獲取對象的耦合,但是獲取類限定名的時候還是需要進行修改!

image.png

2.3)反射工廠2.0

下麵我們可以用properties屬性配置文件存儲文件限定名,把具體的類限定名和代碼相分離,未來只需要修改此配置文件即可!

image.png

public class BeanFactory {
    private static ConnectionMessage message;
    //創建Properties對象來載入properties屬性配置文件
    private static Properties environment = new Properties();
    private static InputStream resource;

    static {
        //載入bean.properties配置文件
        resource = BeanFactory.class.getResourceAsStream("/bean.properties");
        try {
            environment.load(resource);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    public static ConnectionMessage select() throws Exception {
        Class<?> clazz = Class.forName(environment.getProperty("mysqlMessage"));
        message = (MySQLMessageImpl) clazz.getDeclaredConstructor().newInstance();
        return message;
    }
}

2.3)通用工廠

上面我們的工廠方法基本設計完成了,但是還有點小問題,那就是每次都需要在BeanFactory工廠類寫一個與其對應的對象創建工廠方法,這時我們設計一個通用的工廠方法

public class BeanFactory {
    //創建Properties對象來載入properties屬性配置文件
    private static Properties environment = new Properties();
    private static InputStream resource;

    static {
        //載入bean.properties配置文件
        resource = BeanFactory.class.getResourceAsStream("/bean.properties");
        try {
            environment.load(resource);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
  
    /**
     * @param key 配置文件對應的mysqlMessage和postgresqlMessage
     * @return
     */
    public static Object getBean(String key) {
        Object returnedObject = null;
        try {
            Class<?> clazz = Class.forName(environment.getProperty(key));
            returnedObject = clazz.getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return returnedObject;
    }
}

image.png

一個通用工廠就完成了,但是這種方式你還需要先自己提供工廠類和方法,我們如果用Spring的話,工廠類不用我們手動實現,Spring提供了工廠,使我們可以將更多精力放在核心代碼的開發處理上。

2、IoC---控制反轉

簡介:控制反轉(Inversion of Control,縮寫為IoC),它不是一門技術,而是面向對象編程中的一種設計思想,可以用來降低代碼之間的耦合度,能夠指導我們如何設計出松耦合、更優良的程式。

核心: 將對象的創建權交出去,將對象和對象之間關係的管理權交出去,由第三方容器來負責創建與維護 。

目標:降低程式耦合度,提高程式擴展力

控制反轉,反轉的是什麼?

  • 將對象的創建權利交出去,即不在程式中採用硬編碼的方式來new對象,而是交給第三方容器負責
  • 將對象和對象之間關係的維護權交出去,交給第三方容器負責

實現方式:依賴註入(Dependency Injection)與依賴查找(Dependency Lookup)

  • 依賴註入:Spring創建對象的過程中,將對象依賴屬性通過配置進行註入,常見的實現方式:
    • set註入
    • 構造註入

總結:

  1. IOC 就是一種控制反轉的思想, 而 DI 是對IoC的一種具體實現
  2. Bean管理:Bean對象的創建,以及Bean對象中屬性的賦值(或者叫做Bean對象之間關係的維護)

相關名詞

容器:可以管理對象的生命周期、對象與對象之間的依賴關係

實體類:

  • POJO(Plain Old Java Object):是Martin Fowler、Rebecca Parsons和Josh MacKenzie在2000年的一次演講的時候提出來的。按照Martin Fowler的解釋是“Plain Old Java Object”,從字面上翻譯為“純潔老式的Java對象”,但大家都使用“簡單java對象”來稱呼它。POJO的內在含義是指:那些沒有繼承任何類、也沒有實現任何介面,更沒有被其它框架侵入的java對象。不允許有業務方法,也不能攜帶connection之類的方法,實際就是普通JavaBeans。
  • JavaBean:是一種JAVA語言寫成的可重用組件。JavaBean符合一定規範編寫的Java類,不是一種技術,而是一種規範。大家針對這種規範,總結了很多開發技巧、工具函數。符合這種規範的類,可以被其它的程式員或者框架使用。它的方法命名,構造及行為必須符合特定的約定:

1、所有屬性為private。

2、這個類必須有一個公共的預設構造函數。即是提供無參數的構造器。

3、這個類的屬性使用getter和setter來訪問,其他方法遵從標準命名規範。

4、這個類應是可序列化的。實現serializable介面。

因為這些要求主要是靠約定而不是靠實現介面,所以許多開發者把JavaBean看作遵從特定命名約定的POJO。

POJO與JavaBean的區別:

POJO JavaBean
許可權控制 沒有對成員提供太多控制 提供對成員的完全控制
可序列化 可以實現 應該實現
欄位訪問 具有任何可見性,可以直接訪問 欄位只有私人可見性,只能由getter和setter訪問
無參構造 可以沒有 必須具有
使用場景 當您不想限製成員並讓用戶完全訪問您的實體時使用它 當您要向用戶提供您的實體,但僅向實體的一部分提供服務時,將使用它

POJO類和Bean均用於定義Java對象,以提高其可讀性和可重用性。POJO沒有其他限制,而bean是具有某些限制的特殊POJO。

  • SpringBean:受Spring管理的對象,所有能受Spring容器管理的對象都可以成為SpringBean。Spring中的bean,是通過配置文件、javaconfig等的設置,由Spring自動實例化,用完後自動銷毀的對象。

SpringBean和JavaBean的區別:

JavaBean SpringBean
用處不同 更多地作為值傳遞參數 用處幾乎無處不在,任何組件都可以被稱為bean
寫法不同 作為值對象,要求每個屬性都提供getter和setter方法 只需為接受設值註入的屬性提供setter方法
生命周期不同 傳統javabean作為值對象傳遞,不接受任何容器管理其生命周期 spring管理其生命周期行為

Entity Bean:是域模型對象,用於實現O/R映射,負責將資料庫中的表記錄映射為記憶體中的Entity對象,事實上,創建一個Entity Bean對象相當於新建一條記錄,刪除一個 Entity Bean會同時從資料庫中刪除對應記錄,修改一個Entity Bean時,容器會自動將Entity Bean的狀態和資料庫同步。

三、入門程式

1、引入依賴

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>6.0.4</version>
</dependency>

當引入Spring-webmvc依賴之後,表示將Spring的基礎依賴也一起引入了

image.png

有的教程可能引得是spring-context依賴,此依賴是除了web部分其餘的基礎依賴都會引進來,它們一般是在Spring MVC的時候再引入spring-webmvc依賴。

2、創建java類

public class HelloWorld {
    public void sayHello(){
        System.out.println("hello world");
    }
}

3、創建配置文件

在resources目錄創建一個 Spring 配置文件 bean.xml(配置文件名稱可隨意命名)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<!--
    配置HelloWorld所對應的bean,表示將HelloWorld的對象交給Spring的IOC容器管理
    通過bean標簽配置IOC容器所管理的bean
    屬性:
        id:設置bean的唯一標識
        class:設置bean所對應類型的全限定名
    -->
    <bean id="hello" class="com.ty.demo.bean.HelloWorld"></bean>

</beans>

4、測試程式

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
        context.getBean("hello", HelloWorld.class).sayHello();
    }
}

5、簡單分析

這裡我們這是簡單介紹一下基本原理,Spring整個Bean的創建過程很複雜,之後再一點點介紹!

  1. 底層利用通過反射機制調用無參數構造方法

image.png

16751582110323017064ffy

  1. Spring創建對象就像之前我們使用Properties的步驟類似,它使用的是dom4j解析beans.xml文件,從中獲取class屬性值,類的全類名;然後通過反射機制調用無參數構造方法創建對象
Class.forName("com.ty.demo.bean.HelloWorld").getDeclaredConstructor().newInstance()
  1. 創建好的對象存儲在ConcurrentHashMap中

bean對象最終存儲在spring容器中,在spring源碼底層就是一個map集合,存儲bean的map在DefaultListableBeanFactory類中:

image.png

Spring容器載入到Bean類時 , 會把這個類的描述信息, 以包名加類名的方式存到beanDefinitionMap 中,
Map<String,BeanDefinition>

  • 其中 String是Key , 預設是類名首字母小寫 ,
  • BeanDefinition , 存的是類的定義(描述信息) ,
  • 我們通常叫BeanDefinition介面為 : bean的定義對象。

6、SpringTest測試

前面通過ApplicationContext啟動了Spring容器,並實現了配置文件的載入,但這樣處理並不能體現出Spring的運行特征。為了更好地還原現實的開發場景,可利用SpringTest依賴庫和JUnit實現測試環境下的Spring容器啟動,且可以使用@Autowired代替getBean方法實現自動註入。

引入依賴

 <dependency>
     <groupId>org.junit.jupiter</groupId>
     <artifactId>junit-jupiter</artifactId>
     <version>5.8.2</version>
     <scope>test</scope>
</dependency>

<dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-test</artifactId>
     <version>6.0.4</version>
</dependency>

測試程式

@ContextConfiguration(locations = {"classpath:bean.xml"})
@ExtendWith(SpringExtension.class)
public class MyTest {
    @Autowired
    private HelloWorld helloWorld;

    @Test
    void testHelloWorld() {
        helloWorld.sayHello();
    }
}
  • @ContextConfiguration:表示Spring配置文件所在的目錄。本程式通過classpath進行載入,由於src/main/resources屬於源目錄,所以目錄中保存的所有資源將自動設置在CLASSPATH之中
  • @ExtendWith(SpringExtension.class):表示要使用的測試工具類型。
  • @Autowired:自動註入

7、整合logback日誌

在項目開發中,日誌十分的重要,不管是記錄運行情況還是定位線上問題,都離不開對日誌的分析。日誌記錄了系統行為的時間、地點、狀態等相關信息,能夠幫助我們瞭解並監控系統狀態,在發生錯誤或者接近某種危險狀態時能夠及時提醒我們處理,同時在系統產生問題時,能夠幫助我們快速的定位、診斷並解決問題。

引入依賴

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.4.5</version>
    <scope>test</scope>
</dependency>

測試程式

image.png

image.png

作者:貓的薛定諤
出處:https://www.cnblogs.com/hanyu-2020/

---------------------------------------------------------

個性簽名:獨學而無友,則孤陋而寡聞。做一個靈魂有趣的人!

如果覺得這篇文章對你有小小的幫助的話,記得在右下角點個“推薦”哦,博主在此感謝!

本文內容若有疏漏請多多包涵,如有錯誤麻煩請指正,如有想法交流非常歡迎在下方評論!


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

-Advertisement-
Play Games
更多相關文章
  • 這篇僅為自己工作中在 js 和 ts 交叉鬥智鬥勇的實踐中留下的經驗,不一定完全、合理,僅供參考,有錯漏難免,有則評論區指出。 前置知識 - JavaScript 的各種模塊化情況 全局模塊,在 globalThis 上可以訪問,一般是 iife 庫程式 ES 模塊 CommonJS 模塊 前置知識 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 在我們開發項目中,經常會遇到預覽圖片的需求。也就是點擊圖片,會全屏顯示該圖片。需求很簡單,但是如何讓實現更優雅就需要花點心思了。 最終效果圖 基礎版本 實現方式 點擊圖片,創建蒙層,克隆圖片 將圖片添加定位屬性,並添加到蒙層中 將蒙層添加 ...
  • DHTMLX提供有效且專業設計的JavaScript/HTML5工具,使開發人員能夠以更少的時間和精力創建具有豐富界面和快速性能的複雜Web和移動應用程式。 ...
  • 1.CSS 參考手冊 2.元素的分類 首先我們要知道一共有幾種元素 1.行內元素(可以與其他行內元素位於同一行,不會以新行開始高度、寬度不能設置) 2.塊級元素(每個塊級元素都從新的一行開始,其後的元素也另起一行。預設排列方式:從上至下元素的高度、寬度、行高、內外邊距都可設置) 3.行內塊元素(和其 ...
  • refs 字元串形式refs-過時了 // ref key為自命名內容, value為節點 input class Demo extends React.Component { showData = () => { // 拿到的是真實DOM const { input1 } = this.refs; ...
  • 大部分同學都知道,在 CSS 世界中,有 vw、vh、vmax、vmin 這幾個與視口 Viewport 相關的單位。 正常而言: 1vw 等於1/100的視口寬度 (Viewport Width) 1vh 等於1/100的視口高度 (Viewport Height) vmin — vmin 的值是 ...
  • JQuery動態生成的按鈕無法觸發問題與解決方法 起因: 利用JQuery動態添加的按鈕無法通過$(selector).click方法觸發點擊事件 //在網頁載入完成後動態添加表格 $(function () { //通過Ajax向後臺請求程式 $.ajax({ method : "post", u ...
  • 金融社區優惠文章是基於京東商城優惠商品批量化自動生成的,每日通過不同的渠道獲取到待生成的SKU列表,並根據條件生成優惠文章。 但是,生成優惠文章之後續衍生問題:該商品無優惠了,對應文章需要做取消推薦或下架處理,怎樣能更快的知道該商品無優惠了呢? ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...