澶栬浜洪兘鑳界湅鎳傜殑WebFlux锛岄敊杩囦簡琛�浜忥紒

鍓嶈█

鍙湁鍏夊ご鎵嶈兘鍙樺己銆�

鏂囨湰宸叉敹褰曡嚦鎴戠殑GitHub浠撳簱锛屾杩嶴tar锛�https://github.com/ZhongFuCheng3y/3y

鏈枃鐭ヨ瘑鐐规灦鏋勶細

澶栬浜洪兘鑳界湅鎳傜殑WebFlux锛岄敊杩囦簡琛�浜忥紒_第1张图片

濡傛灉鏈夊叧娉ㄦ垜鍏紬鍙锋枃绔犵殑鍚屽灏变細鍙戠幇锛屾渶杩戞垜涓嶅畾鏃惰浆鍙戜簡涓�浜涙瘮杈冨ソ鐨刉ebFlux鐨勬枃绔狅紝鍥犱负鎴戞渶杩戝湪瀛︺��

鎴戜箣鍓嶄篃璇磋繃锛屽涔犱竴椤规妧鏈箣鍓嶏紝鍏堣浜嗚В涓轰粈涔堣瀛﹁繖椤规妧鏈�傚叾瀹炶繖娆″涔�WebFlux涔熸病鏈夊澶х殑鍘熺敓鍔ㄥ姏锛屼富瑕佹槸鍦ㄦ垜浠粍鍐呬細杞祦鍋氫竴娆℃妧鏈垎浜紝鑰屾垜鍙堜笉鐭ラ亾鍒嗕韩浠�涔堟瘮杈冨ソ...

涔嬪墠鍦ㄥ垵瀛﹀ぇ鏁版嵁鐩稿叧鐨勭煡璇嗭紝浣嗘槸杩欎竴鍧楃殑鏃堕棿绾夸細鎷夊緱姣旇緝闀匡紝鎰熻璧朵笉鍙婂皬缁勫唴鍒嗕韩锛堣�岀粍鍐呯殑鍚屽鍙堝ぇ閮ㄥ垎閮芥噦澶ф暟鎹紝灏卞彧鏈夋垜涓�涓彍楦★紝娉洰)銆傛墍浠ワ紝鎯崇殑鏄細鈥滆涓嶆垜瀛︾偣鏂颁笢瑗挎悶鎼烇紵鈥濄�備簬鏄氨鑺变簡鐐规椂闂村WebFlux鍟

杩欑瘒鏂囩珷涓昏璁茶В浠�涔堟槸WebFlux锛屽甫棰嗗ぇ瀹跺叆涓棬锛屽笇鏈涘澶у鏈夋墍甯姪锛堣嚦灏戠湅瀹岃繖绡囨枃绔狅紝鐭ラ亾WebFlux鏄共鍢涚敤鐨�)

涓�銆佷粈涔堟槸WebFlux锛�

鎴戜滑浠�Spring鐨勫畼缃戞媺涓嬩竴鐐圭偣灏卞彲浠ョ湅鍒颁粙缁�WebFlux鐨勫湴鏂逛簡

澶栬浜洪兘鑳界湅鎳傜殑WebFlux锛岄敊杩囦簡琛�浜忥紒_第2张图片

浠庡畼缃戠殑绠�浠嬩腑鎴戜滑鑳藉緱鍑轰粈涔堟牱鐨勪俊鎭紵

  • 鎴戜滑绋嬪簭鍛樺線寰�鏍规嵁涓嶅悓鐨勫簲鐢ㄥ満鏅�夋嫨涓嶅悓鐨勬妧鏈�锛屾湁鐨勫満鏅�傚悎鐢ㄤ簬鍚屾闃诲鐨勶紝鏈夌殑鍦烘櫙閫傚悎鐢ㄤ簬寮傛闈為樆濉炵殑銆傝��Spring5鎻愪緵浜嗕竴鏁村鍝嶅簲寮�(闈為樆濉�)鐨勬妧鏈爤渚涙垜浠娇鐢�(鍖呮嫭Web鎺у埗鍣ㄣ�佹潈闄愭帶鍒躲�佹暟鎹闂眰绛夌瓑)銆�
  • 鑰屽乏渚х殑鍥惧垯鏄妧鏈爤鐨勫姣斿暒锛�
    • 鍝嶅簲寮忎竴鑸敤Netty鎴栬�匰ervlet 3.1鐨勫鍣�(鍥犱负鏀寔寮傛闈為樆濉�)锛岃�孲ervlet鎶�鏈爤鐢ㄧ殑鏄疭ervlet瀹瑰櫒
    • 鍦╓eb绔紝鍝嶅簲寮忕敤鐨勬槸WebFlux锛孲ervlet鐢ㄧ殑鏄疭pringMVC
    • .....

鎬荤粨璧锋潵锛學ebFlux鍙槸鍝嶅簲寮忕紪绋嬩腑鐨勪竴閮ㄥ垎(鍦╓eb鎺у埗绔�)锛屾墍浠ヤ竴鑸垜浠敤瀹冧笌SpringMVC鏉ュ姣斻��

浜屻�佸浣曠悊瑙e搷搴斿紡缂栫▼锛�

鍦ㄤ笂闈㈡彁鍒颁簡鍝嶅簲寮忕紪绋�(Reactive Programming)锛岃�學ebFlux鍙槸鍝嶅簲寮忕紪绋嬬殑鍏朵腑涓�涓妧鏈爤鑰屽凡锛屾墍浠ユ垜浠厛鏉ユ帰璁ㄤ竴涓嬩粈涔堟槸鍝嶅簲寮忕紪绋�

浠庣淮鍩虹櫨绉戦噷杈规垜浠緱鍒扮殑瀹氫箟锛�

reactive programming is a declarative programming paradigm concerned with data streams and the propagation of change

鍝嶅簲寮忕紪绋嬶紙reactive programming锛夋槸涓�绉嶅熀浜庢暟鎹祦锛坉ata stream锛夊拰鍙樺寲浼犻�掞紙propagation of change锛夌殑澹版槑寮忥紙declarative锛夌殑缂栫▼鑼冨紡

鍦ㄧ淮鍩虹櫨绉戜笂涔熶妇浜嗕釜灏忎緥瀛愶細

澶栬浜洪兘鑳界湅鎳傜殑WebFlux锛岄敊杩囦簡琛�浜忥紒_第3张图片

鎰忔�濆ぇ姒傚涓嬶細

  • 鍦ㄥ懡浠ゅ紡缂栫▼(鎴戜滑鐨勬棩甯哥紪绋嬫ā寮�)涓嬶紝寮忓瓙a=b+c锛岃繖灏辨剰鍛崇潃a鐨勫�兼槸鐢�b鍜�c璁$畻鍑烘潵鐨勩�傚鏋�b鎴栬��c鍚庣画鏈夊彉鍖栵紝涓嶄細褰卞搷鍒�a鐨勫��
  • 鍦ㄥ搷搴斿紡缂栫▼涓嬶紝寮忓瓙a:=b+c锛岃繖灏辨剰鍛崇潃a鐨勫�兼槸鐢�b鍜�c璁$畻鍑烘潵鐨勩�備絾濡傛灉b鎴栬��c鐨勫�煎悗缁湁鍙樺寲锛�浼氬奖鍝�鍒�a鐨勫��

鎴戣涓轰笂闈㈢殑渚嬪瓙宸茬粡鍙互甯姪鎴戜滑鐞嗚В鍙樺寲浼犻�掞紙propagation of change锛�

閭f暟鎹祦锛坉ata stream锛夊拰澹版槑寮忥紙declarative锛夋�庝箞鐞嗚В鍛紵閭e彲浠ユ彁涓�鎻愭垜浠殑Stream娴佷簡銆備箣鍓嶅啓杩嘗ambda琛ㄨ揪寮忓拰Stream娴佺殑鏂囩珷锛屽ぇ瀹跺彲浠ュ厛鍘荤湅鐪嬶細

  • 鏈�杩戝鍒扮殑Lambda琛ㄨ揪寮忓熀纭�鐭ヨ瘑
  • 鎵嬫妸鎵嬪甫浣犱綋楠孲tream娴�

Lambda鐨勮娉曟槸杩欐牱鐨�(Stream娴佺殑浣跨敤浼氭秹鍙婂埌寰堝Lambda琛ㄨ揪寮忕殑涓滆タ锛屾墍浠ヤ竴鑸厛瀛ambda鍐嶅Stream娴�)锛�

澶栬浜洪兘鑳界湅鎳傜殑WebFlux锛岄敊杩囦簡琛�浜忥紒_第4张图片

Stream娴佺殑浣跨敤鍒嗕负涓変釜姝ラ(鍒涘缓Stream娴併�佹墽琛屼腑闂存搷浣溿�佹墽琛屾渶缁堟搷浣�)锛�

澶栬浜洪兘鑳界湅鎳傜殑WebFlux锛岄敊杩囦簡琛�浜忥紒_第5张图片

鎵ц涓棿鎿嶄綔瀹為檯涓婂氨鏄粰鎴戜滑鎻愪緵浜嗗緢澶氱殑API鍘绘搷浣淪tream娴佷腑鐨勬暟鎹�(姹傚拰/鍘婚噸/杩囨护)绛夌瓑

澶栬浜洪兘鑳界湅鎳傜殑WebFlux锛岄敊杩囦簡琛�浜忥紒_第6张图片

璇翠簡杩欎箞澶氾紝鎬庝箞鐞嗚В鏁版嵁娴佸拰澹版槑寮忓憿锛熷叾瀹炴槸杩欐牱鐨勶細

  • 鏈潵鏁版嵁鏄垜浠嚜琛屽鐞嗙殑锛屽悗鏉ユ垜浠妸瑕�澶勭悊鐨勬暟鎹娊璞″嚭鏉�锛堝彉鎴愪簡鏁版嵁娴侊級锛岀劧鍚�閫氳繃API鍘诲鐞�鏁版嵁娴佷腑鐨勬暟鎹紙鏄0鏄庡紡鐨勶級

姣斿涓嬮潰鐨勪唬鐮侊紱灏嗘暟缁勪腑鐨勬暟鎹彉鎴�鏁版嵁娴�锛岄�氳繃鏄惧紡澹版槑璋冪敤.sum()鏉ュ鐞嗘暟鎹祦涓殑鏁版嵁锛屽緱鍒版渶缁堢殑缁撴灉锛�

public static void main(String[] args) {
    int[] nums = { 1, 2, 3 };
    int sum2 = IntStream.of(nums).parallel().sum();
    System.out.println("缁撴灉涓猴細" + sum2);
}

濡傚浘涓嬫墍绀猴細

澶栬浜洪兘鑳界湅鎳傜殑WebFlux锛岄敊杩囦簡琛�浜忥紒_第7张图片

2.1 鍝嶅簲寮忕紪绋�->寮傛闈為樆濉�

涓婇潰璁蹭簡鍝嶅簲寮忕紪绋嬫槸浠�涔堬細

鍝嶅簲寮忕紪绋嬶紙reactive programming锛夋槸涓�绉嶅熀浜庢暟鎹祦锛坉ata stream锛夊拰鍙樺寲浼犻�掞紙propagation of change锛夌殑澹版槑寮忥紙declarative锛夌殑缂栫▼鑼冨紡

涔熻瑙d簡鏁版嵁娴�/鍙樺寲浼犻��/澹版槑寮忔槸浠�涔堟剰鎬濓紝浣嗚鍒板搷搴斿紡缂栫▼灏辩涓嶅紑寮傛闈為樆濉�銆�

浠嶴pring瀹樼綉浠嬬粛WebFlux鐨勪俊鎭垜浠氨鍙互鍙戠幇asynchronous, nonblocking 杩欐牱鐨勫瓧鏍凤紝鍥犱负鍝嶅簲寮忕紪绋嬪畠鏄紓姝�鐨勶紝涔熷彲浠ョ悊瑙f垚鍙樺寲浼犻��瀹冩槸寮傛鎵ц鐨勩��

濡備笅鍥撅紝鍚堣鐨勯噾棰濅細鍙楀叾浠栫殑閲戦褰卞搷(鏇存柊鐨勮繃绋嬫槸寮傛鐨�)锛�

澶栬浜洪兘鑳界湅鎳傜殑WebFlux锛岄敊杩囦簡琛�浜忥紒_第8张图片

鎴戜滑鐨凧DK8 Stream娴佹槸鍚屾鐨勶紝瀹冨氨涓嶉�傚悎鐢ㄤ簬鍝嶅簲寮忕紪绋嬶紙浣嗗熀纭�鐨勭敤娉曟槸闇�瑕佹噦鐨勶紝鍥犱负鍝嶅簲寮忔祦缂栫▼閮芥槸鎿嶄綔娴�鍢涳級

鑰屽湪JDK9 宸茬粡鏀寔鍝嶅簲寮忔祦浜嗭紝涓嬮潰鎴戜滑鏉ョ湅涓�涓�

涓夈�丣DK9 Reactive

鍝嶅簲寮忔祦鐨勮鑼冩棭宸茬粡琚彁鍑轰簡锛氶噷闈㈡彁鍒颁簡锛�

Reactive Streams is an initiative to provide a standard for asynchronous stream processing with non-blocking back pressure ----->http://www.reactive-streams.org/

缈昏瘧鍐嶅姞鐐逛俊鎭細

鍝嶅簲寮忔祦(Reactive Streams)閫氳繃瀹氫箟涓�缁勫疄浣擄紝鎺ュ彛鍜屼簰鎿嶄綔鏂规硶锛岀粰鍑轰簡瀹炵幇寮傛闈為樆濉�鑳屽帇鐨勬爣鍑嗐�傜涓夋柟閬靛惊杩欎釜鏍囧噯鏉ュ疄鐜板叿浣撶殑瑙e喅鏂规锛屽父瑙佺殑鏈塕eactor锛孯xJava锛孉kka Streams锛孯atpack绛夈��

瑙勮寖閲屽ご瀹為檯涓婂氨鏄畾涔変簡鍥涗釜鎺ュ彛锛�

澶栬浜洪兘鑳界湅鎳傜殑WebFlux锛岄敊杩囦簡琛�浜忥紒_第9张图片

Java 骞冲彴鐩村埌 JDK 9鎵嶆彁渚涗簡瀵逛簬Reactive鐨勫畬鏁存敮鎸侊紝JDK9涔熷畾涔変簡涓婅堪鎻愬埌鐨勫洓涓帴鍙o紝鍦�java.util.concurrent鍖呬笂

澶栬浜洪兘鑳界湅鎳傜殑WebFlux锛岄敊杩囦簡琛�浜忥紒_第10张图片

涓�涓�氱敤鐨勬祦澶勭悊鏋舵瀯涓�鑸細鏄繖鏍风殑锛�鐢熶骇鑰呬骇鐢熸暟鎹紝瀵规暟鎹繘琛屼腑闂村鐞嗭紝娑堣垂鑰呮嬁鍒版暟鎹秷璐�)锛�

娴佸紡澶勭悊鏋舵瀯

  • 鏁版嵁鏉ユ簮锛屼竴鑸О涓虹敓浜ц�咃紙Producer锛�
  • 鏁版嵁鐨勭洰鐨勫湴锛屼竴鑸О涓烘秷璐硅��(Consumer)
  • 鍦ㄥ鐞嗘椂锛屽鏁版嵁鎵ц鏌愪簺鎿嶄綔涓�涓垨澶氫釜澶勭悊闃舵銆傦紙Processor)

鍒拌繖閲屾垜浠啀鐪嬪洖鍝嶅簲寮忔祦鐨勬帴鍙o紝鎴戜滑搴旇灏辫兘鎳備簡锛�

  • Publisher锛堝彂甯冭��)鐩稿綋浜庣敓浜ц��(Producer)
  • Subscriber(璁㈤槄鑰�)鐩稿綋浜庢秷璐硅��(Consumer)
  • Processor灏辨槸鍦ㄥ彂甯冭�呬笌璁㈤槄鑰呬箣闂村鐞嗘暟鎹敤鐨�

鍦ㄥ搷搴斿紡娴佷笂鎻愬埌浜哹ack pressure锛堣儗鍘�)杩欎箞涓�涓蹇碉紝鍏跺疄闈炲父濂界悊瑙c�傚湪鍝嶅簲寮忔祦瀹炵幇寮傛闈為樆濉炴槸鍩轰簬鐢熶骇鑰呭拰娑堣垂鑰呮ā寮忕殑锛岃�岀敓浜ц�呮秷璐硅�呭緢瀹规槗鍑虹幇鐨勪竴涓棶棰樺氨鏄細鐢熶骇鑰呯敓浜ф暟鎹浜嗭紝灏辨妸娑堣垂鑰呯粰鍘嬪灝浜�銆�

鑰岃儗鍘嬭鐧戒簡灏辨槸锛�娑堣垂鑰呰兘鍛婅瘔鐢熶骇鑰呰嚜宸遍渶瑕佸灏戦噺鐨勬暟鎹�銆傝繖閲屽氨鏄�Subscription鎺ュ彛鎵�鍋氱殑浜嬨��

涓嬮潰鎴戜滑鏉ョ湅鐪婮DK9鎺ュ彛鐨勬柟娉曪紝鎴栬灏辨洿鍔犺兘鐞嗚В涓婇潰鎵�璇寸殑璇濅簡锛�

// 鍙戝竷鑰�(鐢熶骇鑰�)
public interface Publisher {
    public void subscribe(Subscriber s);
}
// 璁㈤槄鑰�(娑堣垂鑰�)
public interface Subscriber {
    public void onSubscribe(Subscription s);
    public void onNext(T t);
    public void onError(Throwable t);
    public void onComplete();
}
// 鐢ㄤ簬鍙戝竷鑰呬笌璁㈤槄鑰呬箣闂寸殑閫氫俊(瀹炵幇鑳屽帇锛氳闃呰�呰兘澶熷憡璇夌敓浜ц�呴渶瑕佸灏戞暟鎹�)
public interface Subscription {
    public void request(long n);
    public void cancel();
}
// 鐢ㄤ簬澶勭悊鍙戝竷鑰� 鍙戝竷娑堟伅鍚庯紝瀵规秷鎭繘琛屽鐞嗭紝鍐嶄氦鐢辨秷璐硅�呮秷璐�
public interface Processor extends Subscriber, Publisher {
}

3.1 鐪嬩釜渚嬪瓙

浠g爜涓湁澶ч噺鐨勬敞閲婏紝鎴戝氨涓嶅BB浜嗭紝寤鸿鐩存帴澶嶅埗璺戜竴涓嬬湅鐪嬶細

class MyProcessor extends SubmissionPublisher
        implements Processor {

    private Subscription subscription;

    @Override
    public void onSubscribe(Subscription subscription) {
        // 淇濆瓨璁㈤槄鍏崇郴, 闇�瑕佺敤瀹冩潵缁欏彂甯冭�呭搷搴�
        this.subscription = subscription;

        // 璇锋眰涓�涓暟鎹�
        this.subscription.request(1);
    }

    @Override
    public void onNext(Integer item) {
        // 鎺ュ彈鍒颁竴涓暟鎹�, 澶勭悊
        System.out.println("澶勭悊鍣ㄦ帴鍙楀埌鏁版嵁: " + item);

        // 杩囨护鎺夊皬浜�0鐨�, 鐒跺悗鍙戝竷鍑哄幓
        if (item > 0) {
            this.submit("杞崲鍚庣殑鏁版嵁:" + item);
        }

        // 澶勭悊瀹岃皟鐢╮equest鍐嶈姹備竴涓暟鎹�
        this.subscription.request(1);

        // 鎴栬�� 宸茬粡杈惧埌浜嗙洰鏍�, 璋冪敤cancel鍛婅瘔鍙戝竷鑰呬笉鍐嶆帴鍙楁暟鎹簡
        // this.subscription.cancel();
    }

    @Override
    public void onError(Throwable throwable) {
        // 鍑虹幇浜嗗紓甯�(渚嬪澶勭悊鏁版嵁鐨勬椂鍊欎骇鐢熶簡寮傚父)
        throwable.printStackTrace();

        // 鎴戜滑鍙互鍛婅瘔鍙戝竷鑰�, 鍚庨潰涓嶆帴鍙楁暟鎹簡
        this.subscription.cancel();
    }

    @Override
    public void onComplete() {
        // 鍏ㄩ儴鏁版嵁澶勭悊瀹屼簡(鍙戝竷鑰呭叧闂簡)
        System.out.println("澶勭悊鍣ㄥ鐞嗗畬浜�!");
        // 鍏抽棴鍙戝竷鑰�
        this.close();
    }

}

public class FlowDemo2 {

    public static void main(String[] args) throws Exception {
        // 1. 瀹氫箟鍙戝竷鑰�, 鍙戝竷鐨勬暟鎹被鍨嬫槸 Integer
        // 鐩存帴浣跨敤jdk鑷甫鐨凷ubmissionPublisher
        SubmissionPublisher publiser = new SubmissionPublisher();

        // 2. 瀹氫箟澶勭悊鍣�, 瀵规暟鎹繘琛岃繃婊�, 骞惰浆鎹负String绫诲瀷
        MyProcessor processor = new MyProcessor();

        // 3. 鍙戝竷鑰� 鍜� 澶勭悊鍣� 寤虹珛璁㈤槄鍏崇郴
        publiser.subscribe(processor);

        // 4. 瀹氫箟鏈�缁堣闃呰��, 娑堣垂 String 绫诲瀷鏁版嵁
        Subscriber subscriber = new Subscriber() {

            private Subscription subscription;

            @Override
            public void onSubscribe(Subscription subscription) {
                // 淇濆瓨璁㈤槄鍏崇郴, 闇�瑕佺敤瀹冩潵缁欏彂甯冭�呭搷搴�
                this.subscription = subscription;

                // 璇锋眰涓�涓暟鎹�
                this.subscription.request(1);
            }

            @Override
            public void onNext(String item) {
                // 鎺ュ彈鍒颁竴涓暟鎹�, 澶勭悊
                System.out.println("鎺ュ彈鍒版暟鎹�: " + item);

                // 澶勭悊瀹岃皟鐢╮equest鍐嶈姹備竴涓暟鎹�
                this.subscription.request(1);

                // 鎴栬�� 宸茬粡杈惧埌浜嗙洰鏍�, 璋冪敤cancel鍛婅瘔鍙戝竷鑰呬笉鍐嶆帴鍙楁暟鎹簡
                // this.subscription.cancel();
            }

            @Override
            public void onError(Throwable throwable) {
                // 鍑虹幇浜嗗紓甯�(渚嬪澶勭悊鏁版嵁鐨勬椂鍊欎骇鐢熶簡寮傚父)
                throwable.printStackTrace();

                // 鎴戜滑鍙互鍛婅瘔鍙戝竷鑰�, 鍚庨潰涓嶆帴鍙楁暟鎹簡
                this.subscription.cancel();
            }

            @Override
            public void onComplete() {
                // 鍏ㄩ儴鏁版嵁澶勭悊瀹屼簡(鍙戝竷鑰呭叧闂簡)
                System.out.println("澶勭悊瀹屼簡!");
            }

        };

        // 5. 澶勭悊鍣� 鍜� 鏈�缁堣闃呰�� 寤虹珛璁㈤槄鍏崇郴
        processor.subscribe(subscriber);

        // 6. 鐢熶骇鏁版嵁, 骞跺彂甯�
        publiser.submit(-111);
        publiser.submit(111);

        // 7. 缁撴潫鍚� 鍏抽棴鍙戝竷鑰�
        // 姝e紡鐜 搴旇鏀� finally 鎴栬�呬娇鐢� try-resouce 纭繚鍏抽棴
        publiser.close();

        // 涓荤嚎绋嬪欢杩熷仠姝�, 鍚﹀垯鏁版嵁娌℃湁娑堣垂灏遍��鍑�
        Thread.currentThread().join(1000);
    }

}

杈撳嚭鐨勭粨鏋滃涓嬶細

澶栬浜洪兘鑳界湅鎳傜殑WebFlux锛岄敊杩囦簡琛�浜忥紒_第11张图片

娴佺▼瀹為檯涓婇潪甯哥畝鍗曠殑锛�

澶栬浜洪兘鑳界湅鎳傜殑WebFlux锛岄敊杩囦簡琛�浜忥紒_第12张图片

鍙傝�冭祫鏂欙細

  • https://yanbin.blog/java-9-talk-reactive-stream/#more-8877
  • https://blog.csdn.net/wudaoshihun/article/details/83070086
  • http://www.spring4all.com/article/6826
  • https://www.cnblogs.com/IcanFixIt/p/7245377.html

Java 8 鐨� Stream 涓昏鍏虫敞鍦ㄦ祦鐨勮繃婊わ紝鏄犲皠锛屽悎骞讹紝鑰� Reactive Stream 鏇磋繘涓�灞傦紝渚ч噸鐨勬槸娴佺殑浜х敓涓庢秷璐癸紝鍗虫祦鍦ㄧ敓浜т笌娑堣垂鑰呬箣闂寸殑鍗忚皟

璇寸櫧浜嗗氨鏄細鍝嶅簲寮忔祦鏄紓姝ラ潪闃诲+娴侀噺鎺у埗鐨�(鍙互鍛婅瘔鐢熶骇鑰呰嚜宸遍渶瑕佸灏戠殑閲�/鍙栨秷璁㈤槄鍏崇郴)

灞曟湜鍝嶅簲寮忕紪绋嬬殑鍦烘櫙搴旂敤锛�

姣斿涓�涓棩蹇楃洃鎺х郴缁燂紝鎴戜滑鐨勫墠绔〉闈㈠皢涓嶅啀闇�瑕侀�氳繃鈥滃懡浠ゅ紡鈥濈殑杞鐨勬柟寮忎笉鏂悜鏈嶅姟鍣ㄨ姹傛暟鎹劧鍚庤繘琛屾洿鏂帮紝鑰屾槸鍦ㄥ缓绔嬪ソ閫氶亾涔嬪悗锛屾暟鎹祦浠庣郴缁熸簮婧愪笉鏂祦鍚戦〉闈紝浠庤�屽睍鐜板疄鏃剁殑鎸囨爣鍙樺寲鏇茬嚎锛�

鍐嶆瘮濡備竴涓ぞ浜ゅ钩鍙帮紝鏈嬪弸鐨勫姩鎬併�佺偣璧炲拰鐣欒█涓嶆槸鎵嬪姩鍒峰嚭鏉ョ殑锛岃�屾槸褰撳悗鍙版暟鎹彉鍖栫殑鏃跺�欒嚜鍔ㄤ綋鐜板埌鐣岄潰涓婄殑銆�

鍥涖�佸叆闂╓ebFlux

鎵簡涓�澶у爢锛岀粓浜庡洖鍒癢ebFlux浜嗐�傜粡杩囦笂闈㈢殑鍩虹锛屾垜浠幇鍦ㄥ凡缁忚兘澶熷緱鍑轰竴浜涚粨璁虹殑浜嗭細

  • WebFlux鏄疭pring鎺ㄥ嚭鍝嶅簲寮忕紪绋嬬殑涓�閮ㄥ垎(web绔�)
  • 鍝嶅簲寮忕紪绋嬫槸寮傛闈為樆濉炵殑(鏄竴绉嶅熀浜庢暟鎹祦锛坉ata stream锛夊拰鍙樺寲浼犻�掞紙propagation of change锛夌殑澹版槑寮忥紙declarative锛夌殑缂栫▼鑼冨紡)

鎴戜滑鍐嶅洖鏉ョ湅瀹樼綉鐨勫浘锛�

澶栬浜洪兘鑳界湅鎳傜殑WebFlux锛岄敊杩囦簡琛�浜忥紒_第13张图片

4.1 绠�鍗曚綋楠學ebFlux

Spring瀹樻柟涓轰簡璁╂垜浠洿鍔�蹇��/骞虫粦鍒癢ebFlux涓婏紝涔嬪墠SpringMVC閭e閮芥槸鏀寔鐨勩�備篃灏辨槸璇达細鎴戜滑鍙互鍍忎娇鐢⊿pringMVC涓�鏍蜂娇鐢ㄧ潃WebFlux銆�

澶栬浜洪兘鑳界湅鎳傜殑WebFlux锛岄敊杩囦簡琛�浜忥紒_第14张图片

WebFlux浣跨敤鐨勫搷搴斿紡娴佸苟涓嶆槸鐢↗DK9骞冲彴鐨勶紝鑰屾槸涓�涓彨鍋�Reactor鍝嶅簲寮忔祦搴撱�傛墍浠ワ紝鍏ラ棬WebFlux鍏跺疄鏇村鏄簡瑙f�庝箞浣跨敤Reactor鐨凙PI锛屼笅闈㈡垜浠潵鐪嬬湅~

Reactor鏄竴涓搷搴斿紡娴侊紝瀹冧篃鏈夊搴旂殑鍙戝竷鑰�(Publisher )锛孯eactor鐨勫彂甯冭�呯敤涓や釜绫绘潵琛ㄧず锛�

  • Mono(杩斿洖0鎴�1涓厓绱�)
  • Flux(杩斿洖0-n涓厓绱�)

鑰岃闃呰�呭垯鏄�Spring妗嗘灦鍘诲畬鎴�

涓嬮潰鎴戜滑鏉ョ湅涓�涓畝鍗曠殑渚嬪瓙(鍩轰簬WebFlux鐜鏋勫缓)锛�

// 闃诲5绉掗挓
private String createStr() {
    try {
        TimeUnit.SECONDS.sleep(5);
    } catch (InterruptedException e) {
    }
    return "some string";
}

// 鏅�氱殑SpringMVC鏂规硶
@GetMapping("/1")
private String get1() {
    log.info("get1 start");
    String result = createStr();
    log.info("get1 end.");
    return result;
}

// WebFlux(杩斿洖鐨勬槸Mono)
@GetMapping("/2")
private Mono get2() {
    log.info("get2 start");
    Mono result = Mono.fromSupplier(() -> createStr());
    log.info("get2 end.");
    return result;
}

棣栧厛锛屽�煎緱璇存槑鐨勬槸锛屾垜浠瀯寤篧ebFlux鐜鍚姩鏃讹紝搴旂敤鏈嶅姟鍣ㄩ粯璁ゆ槸Netty鐨勶細

澶栬浜洪兘鑳界湅鎳傜殑WebFlux锛岄敊杩囦簡琛�浜忥紒_第15张图片

鎴戜滑鍒嗗埆鏉ヨ闂竴涓婼pringMVC鐨勬帴鍙e拰WebFlux鐨勬帴鍙o紝鐪嬩竴涓嬫湁浠�涔堝尯鍒細

SpringMVC锛�

SpringMVC

WebFlux锛�

澶栬浜洪兘鑳界湅鎳傜殑WebFlux锛岄敊杩囦簡琛�浜忥紒_第16张图片

浠庤皟鐢ㄨ��(娴忚鍣�)鐨勮搴﹁�岃█锛屾槸鎰熺煡涓嶅埌鏈変粈涔堝彉鍖栫殑锛屽洜涓洪兘鏄緱绛夊緟5s鎵嶈繑鍥炴暟鎹�備絾鏄紝浠庢湇鍔$鐨勬棩蹇楁垜浠彲浠ョ湅鍑猴紝WebFlux鏄�鐩存帴杩斿洖Mono瀵硅薄鐨�(鑰屼笉鏄儚SpringMVC涓�鐩村悓姝ラ樆濉�5s锛岀嚎绋嬫墠杩斿洖)銆�

杩欐鏄疻ebFlux鐨勫ソ澶勶細鑳藉浠�鍥哄畾鐨勭嚎绋嬫潵澶勭悊楂樺苟鍙�锛堝厖鍒嗗彂鎸ユ満鍣ㄧ殑鎬ц兘锛夈��

WebFlux杩樻敮鎸�鏈嶅姟鍣ㄦ帹閫�(SSE - >Server Send Event)锛屾垜浠潵鐪嬩釜渚嬪瓙锛�

/**
     * Flux : 杩斿洖0-n涓厓绱�
     * 娉細闇�瑕佹寚瀹歁ediaType
     * @return
     */
@GetMapping(value = "/3", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
private Flux flux() {
    Flux result = Flux
        .fromStream(IntStream.range(1, 5).mapToObj(i -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
            }
            return "flux data--" + i;
        }));
    return result;
}

鏁堟灉灏辨槸姣忕浼氱粰娴忚鍣ㄦ帹閫佹暟鎹細

澶栬浜洪兘鑳界湅鎳傜殑WebFlux锛岄敊杩囦簡琛�浜忥紒_第17张图片

闈炲父鎰熻阿浜烘墠浠兘鐪嬪埌杩欓噷锛屽鏋滆繖涓枃绔犲啓寰楄繕涓嶉敊锛岃寰椼�屼笁姝�嶆垜鏈夌偣涓滆タ鐨勮瘽 姹傜偣璧� 姹傚叧娉笍 姹傚垎浜煈� 姹傜暀瑷�馃挰 瀵规殩鐢锋垜鏉ヨ鐪熺殑 闈炲父鏈夌敤锛侊紒锛�

WebFlux鎴戣繕娌″啓瀹岋紝杩欑瘒鍐欎簡WebFlux鏀寔SpringMVC閭e娉ㄨВ鏉ュ紑鍙戯紝涓嬬瘒鍐欏啓濡備綍浣跨敤WebFlux鍙︿竴绉嶆ā寮�(Functional Endpoints)鏉ュ紑鍙戜互鍙婁竴浜涘父瑙佺殑闂杩橀渶瑕佽ˉ鍏呬竴涓媬

鏈凡鏀跺綍鑷虫垜鐨凣itHub绮鹃�夋枃绔狅紝娆㈣繋Star锛�https://github.com/ZhongFuCheng3y/3y

涔愪簬杈撳嚭骞茶揣鐨凧ava鎶�鏈叕浼楀彿锛�Java3y銆傚叕浼楀彿鍐�鏈�300澶氱瘒鍘熷垱鎶�鏈枃绔犮�佹捣閲忚棰戣祫婧愩�佺簿缇庤剳鍥撅紝鍏虫敞鍗冲彲鑾峰彇锛�

澶栬浜洪兘鑳界湅鎳傜殑WebFlux锛岄敊杩囦簡琛�浜忥紒_第18张图片

鍒涗綔涓嶆槗锛屽悇浣嶇殑鏀寔鍜岃鍙紝灏辨槸鎴戝垱浣滅殑鏈�澶у姩鍔涳紝鎴戜滑涓嬬瘒鏂囩珷瑙侊紒 姹傜偣璧� 姹傚叧娉笍 姹傚垎浜煈� 姹傜暀瑷�馃挰

你可能感兴趣的:(澶栬浜洪兘鑳界湅鎳傜殑WebFlux锛岄敊杩囦簡琛�浜忥紒)