精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

哭了!為什么沒早用 Spring 狀態(tài)機?現(xiàn)在代碼優(yōu)雅到發(fā)光

開發(fā) 前端
Spring 狀態(tài)機還有很多高級特性和應用場景等待我們?nèi)ヌ剿?,比如工作流引擎、有限狀態(tài)自動機等。只要我們合理運用,它就能成為我們開發(fā)過程中的得力助手,讓我們的代碼質(zhì)量更上一層樓。

兄弟們,有沒有那么一瞬間,看著自己寫的那些處理狀態(tài)邏輯的代碼,恨不得給自己來兩拳?明明需求看起來挺簡單,就是處理個狀態(tài)轉(zhuǎn)換,結(jié)果寫著寫著,代碼里全是各種 if-else 或者 switch,層層嵌套,跟迷宮似的。不僅自己看著頭疼,同事接手的時候,估計心里也在默默問候咱的祖宗十八代。而且最要命的是,稍微不注意,狀態(tài)判斷錯了,bug 就跟雨后春筍似的冒出來,debug 都能讓人 debug 到懷疑人生。

咱就拿一個常見的訂單業(yè)務來說吧。訂單有創(chuàng)建、支付、發(fā)貨、收貨、取消、退款等等狀態(tài)。一開始,咱可能想著,這不簡單嘛,用 if-else 來判斷當前狀態(tài),然后根據(jù)不同的事件,比如用戶支付、商家發(fā)貨等,來更新訂單狀態(tài)。于是代碼里就出現(xiàn)了這樣的場景:

if (order.getStatus() == OrderStatus.CREATED) {
    if (event == Event.PAY) {
        // 處理支付邏輯
        order.setStatus(OrderStatus.PAID);
    } else if (event == Event.CANCEL) {
        // 處理取消邏輯
        order.setStatus(OrderStatus.CANCELED);
    }
} else if (order.getStatus() == OrderStatus.PAID) {
    if (event == Event.SHIP) {
        // 處理發(fā)貨邏輯
        order.setStatus(OrderStatus.SHIPPED);
    } else if (event == Event.REFUND) {
        // 處理退款邏輯
        order.setStatus(OrderStatus.REFUNDED);
    }
}
// 后面還有一堆類似的判斷...

隨著業(yè)務的不斷擴展,狀態(tài)越來越多,事件也越來越復雜,這樣的代碼簡直就是一場災難。維護起來難不說,要是新增一個狀態(tài)或者修改一個狀態(tài)轉(zhuǎn)換規(guī)則,那得把整個代碼翻個底朝天,還生怕漏掉某個地方,導致出現(xiàn)奇怪的 bug。這時候,咱心里是不是在想,有沒有一種更優(yōu)雅的方式來處理狀態(tài)邏輯呢?別急,今天咱就來聊聊 Spring 狀態(tài)機,用了它,保準讓你的代碼優(yōu)雅到發(fā)光,再也不用為狀態(tài)邏輯處理而發(fā)愁。

一、啥是狀態(tài)機?先把概念搞明白

在說 Spring 狀態(tài)機之前,咱得先弄清楚啥是狀態(tài)機。其實狀態(tài)機這玩意兒,在咱們?nèi)粘I钪须S處可見。比如說自動售貨機,它有不同的狀態(tài),比如等待投幣、等待選擇商品、出貨、找零等。當我們投入硬幣(這就是一個事件),自動售貨機就會從等待投幣狀態(tài)轉(zhuǎn)換到等待選擇商品狀態(tài);當我們選擇了一個商品(又是一個事件),它就會根據(jù)商品價格和我們投入的硬幣金額進行判斷,如果金額足夠,就會轉(zhuǎn)換到出貨狀態(tài),同時可能還會找零。

再比如說電梯,它有停止、運行、開門、關(guān)門等狀態(tài)。當我們在某一層按了電梯按鈕(事件),電梯如果在運行狀態(tài),可能會繼續(xù)運行到目標樓層,然后停止并開門;如果電梯在停止狀態(tài),就會開門讓我們進去,然后關(guān)門運行到我們選擇的樓層。

從計算機科學的角度來說,狀態(tài)機(State Machine)是表示有限個狀態(tài)以及在這些狀態(tài)之間的轉(zhuǎn)移和動作等行為的數(shù)學模型。簡單來說,它由狀態(tài)(State)、事件(Event)、轉(zhuǎn)換(Transition)、動作(Action)和守衛(wèi)條件(Guard)組成。

  • 狀態(tài)(State):對象在其生命周期中的一種條件,比如訂單的創(chuàng)建狀態(tài)、支付狀態(tài)等。
  • 事件(Event):觸發(fā)狀態(tài)轉(zhuǎn)換的消息,比如用戶支付訂單、商家發(fā)貨等。
  • 轉(zhuǎn)換(Transition):從一個狀態(tài)到另一個狀態(tài)的遷移,通常由事件觸發(fā),并且可能需要滿足一定的守衛(wèi)條件。
  • 動作(Action):在狀態(tài)轉(zhuǎn)換過程中執(zhí)行的操作,比如更新訂單狀態(tài)、發(fā)送通知等。
  • 守衛(wèi)條件(Guard):一個布爾表達式,用于判斷事件是否能夠觸發(fā)狀態(tài)轉(zhuǎn)換,比如只有當訂單金額大于 0 時,才能進行支付操作。

狀態(tài)機的好處可太多了。它能讓我們清晰地描述對象的狀態(tài)變化過程,代碼結(jié)構(gòu)更加清晰,易于維護和擴展。而且,它能夠有效地避免狀態(tài)判斷的遺漏和錯誤,提高代碼的健壯性。

二、Spring 狀態(tài)機:Java 開發(fā)者的狀態(tài)管理神器

Spring 狀態(tài)機是 Spring 框架提供的一個用于構(gòu)建狀態(tài)機的模塊,它基于狀態(tài)模式和責任鏈模式,能夠方便地在 Java 應用中實現(xiàn)狀態(tài)機。Spring 狀態(tài)機支持多種狀態(tài)機模型,包括 UML 狀態(tài)機和簡單狀態(tài)機,我們可以根據(jù)具體的業(yè)務需求選擇合適的模型。

(一)Spring 狀態(tài)機的核心概念

狀態(tài)(State)

在 Spring 狀態(tài)機中,狀態(tài)可以分為簡單狀態(tài)和復合狀態(tài)。簡單狀態(tài)就是一個獨立的狀態(tài),比如訂單的創(chuàng)建狀態(tài);復合狀態(tài)可以包含子狀態(tài),比如訂單的處理中狀態(tài)可以包含支付中、發(fā)貨中等子狀態(tài)。我們可以通過枚舉類型來定義狀態(tài),例如:

public enum OrderState {
    CREATED, PAID, SHIPPED, DELIVERED, CANCELED, REFUNDED
}

事件(Event)

事件是觸發(fā)狀態(tài)轉(zhuǎn)換的原因,同樣可以用枚舉類型來定義,例如:

public enum OrderEvent {
    PAY, SHIP, DELIVER, CANCEL, REFUND
}

轉(zhuǎn)換(Transition)

轉(zhuǎn)換定義了從源狀態(tài)到目標狀態(tài)的映射,以及觸發(fā)轉(zhuǎn)換的事件和可能的守衛(wèi)條件、動作。在 Spring 狀態(tài)機中,我們可以通過配置來定義轉(zhuǎn)換規(guī)則。

動作(Action)

動作可以在狀態(tài)轉(zhuǎn)換的不同階段執(zhí)行,比如在事件觸發(fā)時、狀態(tài)轉(zhuǎn)換前、狀態(tài)轉(zhuǎn)換后等。我們可以自定義動作類,實現(xiàn) Action 接口,然后在配置中指定動作的執(zhí)行時機。

守衛(wèi)條件(Guard)

守衛(wèi)條件用于判斷事件是否能夠觸發(fā)狀態(tài)轉(zhuǎn)換,它是一個實現(xiàn)了 Guard 接口的類,返回一個布爾值。例如,只有當訂單未被取消時,才能進行發(fā)貨操作。

(二)Spring 狀態(tài)機的優(yōu)勢

代碼結(jié)構(gòu)清晰

使用 Spring 狀態(tài)機,我們可以將狀態(tài)邏輯從業(yè)務代碼中分離出來,通過配置的方式定義狀態(tài)轉(zhuǎn)換規(guī)則,使得代碼更加簡潔明了,易于理解和維護。

易于擴展

當業(yè)務需求發(fā)生變化,需要新增狀態(tài)或修改狀態(tài)轉(zhuǎn)換規(guī)則時,只需修改狀態(tài)機的配置,而無需修改大量的業(yè)務代碼,降低了代碼的修改成本。

支持復雜狀態(tài)邏輯

Spring 狀態(tài)機支持復合狀態(tài)、子狀態(tài)機等高級特性,能夠處理復雜的業(yè)務狀態(tài)邏輯,比如工作流、有限狀態(tài)自動機等。

與 Spring 生態(tài)集成良好

作為 Spring 框架的一部分,Spring 狀態(tài)機可以無縫集成 Spring 的其他模塊,比如 Spring Boot、Spring Data 等,方便我們構(gòu)建完整的應用系統(tǒng)。

三、手把手教你用 Spring 狀態(tài)機玩轉(zhuǎn)訂單狀態(tài)管理

接下來,咱就以訂單狀態(tài)管理為例,一步步教你如何使用 Spring 狀態(tài)機來實現(xiàn)優(yōu)雅的狀態(tài)邏輯處理。

(一)引入依賴

首先,我們需要在項目中引入 Spring 狀態(tài)機的依賴。如果使用 Spring Boot,只需在 pom.xml 中添加以下依賴:

<dependency>
    <groupId>org.springframework.statemachine</groupId>
    <artifactId>spring-statemachine-core</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.statemachine</groupId>
    <artifactId>spring-statemachine-config</artifactId>
</dependency>

(二)定義狀態(tài)和事件

我們已經(jīng)在前面定義了訂單的狀態(tài)枚舉 OrderState 和事件枚舉 OrderEvent,這里就不再重復了。

(三)配置狀態(tài)機

Spring 狀態(tài)機的配置可以通過 Java 配置類來實現(xiàn),我們需要創(chuàng)建一個配置類,繼承 StateMachineConfigurerAdapter,并覆蓋相關(guān)的方法來定義狀態(tài)機的狀態(tài)、轉(zhuǎn)換、動作和守衛(wèi)條件等。

@Configuration
@EnableStateMachine
public class OrderStateMachineConfig extends StateMachineConfigurerAdapter<OrderState, OrderEvent> {
    // 定義狀態(tài)
    @Override
    public void configure(StateMachineStateConfigurer<OrderState, OrderEvent> states) throws Exception {
        states
           .withStates()
               .initial(OrderState.CREATED) // 初始狀態(tài)
               .states(EnumSet.allOf(OrderState.class));
    }
    // 定義轉(zhuǎn)換
    @Override
    public void configure(StateMachineTransitionConfigurer<OrderState, OrderEvent> transitions) throws Exception {
        transitions
           .withExternal() // 外部轉(zhuǎn)換,會改變狀態(tài)
               .source(OrderState.CREATED) // 源狀態(tài)
               .target(OrderState.PAID) // 目標狀態(tài)
               .event(OrderEvent.PAY) // 觸發(fā)事件
               .action(payAction()) // 執(zhí)行的動作
               .guard(payGuard()) // 守衛(wèi)條件
           .and()
           .withExternal()
               .source(OrderState.PAID)
               .target(OrderState.SHIPPED)
               .event(OrderEvent.SHIP)
               .action(shipAction())
           .and()
           .withExternal()
               .source(OrderState.SHIPPED)
               .target(OrderState.DELIVERED)
               .event(OrderEvent.DELIVER)
               .action(deliverAction())
           .and()
           .withExternal()
               .source(OrderState.CREATED)
               .target(OrderState.CANCELED)
               .event(OrderEvent.CANCEL)
               .action(cancelAction())
           .and()
           .withExternal()
               .source(OrderState.PAID)
               .target(OrderState.REFUNDED)
               .event(OrderEvent.REFUND)
               .action(refundAction());
    }
    // 定義動作
    @Bean
    public Action<OrderState, OrderEvent> payAction() {
        return new Action<OrderState, OrderEvent>() {
            @Override
            public void execute(StateContext<OrderState, OrderEvent> context) {
                // 處理支付動作,比如更新訂單支付時間、調(diào)用支付接口等
                System.out.println("執(zhí)行支付動作");
                Order order = context.getMessage().getHeaders().get("order", Order.class);
                order.setStatus(OrderState.PAID);
                order.setPaymentTime(new Date());
                // 這里可以添加具體的業(yè)務邏輯
            }
        };
    }
    @Bean
    public Action<OrderState, OrderEvent> shipAction() {
        return context -> {
            // 處理發(fā)貨動作,比如生成物流單號、更新發(fā)貨時間等
            System.out.println("執(zhí)行發(fā)貨動作");
            Order order = context.getMessage().getHeaders().get("order", Order.class);
            order.setStatus(OrderState.SHIPPED);
            order.setShipTime(new Date());
            // 這里可以添加具體的業(yè)務邏輯
        };
    }
    // 定義守衛(wèi)條件
    @Bean
    public Guard<OrderState, OrderEvent> payGuard() {
        return context -> {
            // 判斷訂單金額是否大于 0,只有金額大于 0 才能支付
            Order order = context.getMessage().getHeaders().get("order", Order.class);
            return order.getAmount() > 0;
        };
    }
}

在上面的配置中,我們首先定義了狀態(tài),指定了初始狀態(tài)為 CREATED,并包含了所有的訂單狀態(tài)。然后定義了轉(zhuǎn)換規(guī)則,每個轉(zhuǎn)換都指定了源狀態(tài)、目標狀態(tài)、觸發(fā)事件、動作和守衛(wèi)條件(可選)。動作和守衛(wèi)條件通過 Bean 的方式定義,方便重用和測試。

(四)使用狀態(tài)機

配置好狀態(tài)機之后,我們就可以在業(yè)務代碼中使用它了。首先,需要注入 StateMachine 對象:

@Autowired
private StateMachine<OrderState, OrderEvent> orderStateMachine;

然后,在處理事件時,創(chuàng)建消息對象,并將訂單對象作為參數(shù)傳遞給狀態(tài)機:

public void processEvent(Order order, OrderEvent event) {
    // 創(chuàng)建消息,將訂單對象作為參數(shù)
    Message<OrderEvent> message = MessageBuilder.withPayload(event)
       .setHeader("order", order)
       .build();
    // 發(fā)送事件給狀態(tài)機
    orderStateMachine.sendEvent(message);
}

當狀態(tài)機接收到事件后,會根據(jù)配置的轉(zhuǎn)換規(guī)則進行狀態(tài)轉(zhuǎn)換,并執(zhí)行相應的動作和守衛(wèi)條件。

(五)狀態(tài)機監(jiān)聽器

為了更好地監(jiān)控狀態(tài)機的狀態(tài)變化,我們可以添加監(jiān)聽器,監(jiān)聽狀態(tài)的進入、退出和轉(zhuǎn)換等事件。例如:

@Configuration
public class OrderStateMachineListenerConfig {
    @Autowired
    public void configure(StateMachineFactory<OrderState, OrderEvent> factory) {
        factory.getStateMachine().addStateListener(new StateListener<OrderState, OrderEvent>() {
            @Override
            public void stateChanged(State<OrderState, OrderEvent> from, State<OrderState, OrderEvent> to) {
                // 狀態(tài)發(fā)生變化時觸發(fā)
                System.out.println("狀態(tài)從 " + from.getId() + " 轉(zhuǎn)換到 " + to.getId());
            }
        });
        factory.getStateMachine().addTransitionListener(new TransitionListener<OrderState, OrderEvent>() {
            @Override
            public void transitionStarted(Transition<OrderState, OrderEvent> transition) {
                // 轉(zhuǎn)換開始時觸發(fā)
                System.out.println("轉(zhuǎn)換開始:" + transition.getSource().getId() + " -> " + transition.getTarget().getId());
            }
            @Override
            public void transitionEnded(Transition<OrderState, OrderEvent> transition) {
                // 轉(zhuǎn)換結(jié)束時觸發(fā)
                System.out.println("轉(zhuǎn)換結(jié)束:" + transition.getSource().getId() + " -> " + transition.getTarget().getId());
            }
        });
    }
}

通過監(jiān)聽器,我們可以在狀態(tài)轉(zhuǎn)換的各個階段執(zhí)行一些額外的操作,比如記錄日志、發(fā)送通知等。

四、Spring 狀態(tài)機進階:處理復雜業(yè)務場景

(一)復合狀態(tài)和子狀態(tài)機

當業(yè)務場景比較復雜,狀態(tài)之間存在層次關(guān)系時,我們可以使用復合狀態(tài)和子狀態(tài)機。例如,訂單在支付過程中可能有支付中、支付成功、支付失敗等子狀態(tài),我們可以將支付過程定義為一個復合狀態(tài),其中包含這些子狀態(tài)。

public enum OrderState {
    CREATED,
    PAYING(CompositeState.PAYMENT), // 復合狀態(tài)
    PAID,
    PAYMENT_FAILED,
    SHIPPED,
    DELIVERED,
    CANCELED,
    REFUNDED
}

// 復合狀態(tài)枚舉
publicenum CompositeState {
    PAYMENT
}

在配置狀態(tài)機時,我們可以定義復合狀態(tài)及其子狀態(tài):

@Override
public void configure(StateMachineStateConfigurer<OrderState, OrderEvent> states) throws Exception {
    states
       .withStates()
           .initial(OrderState.CREATED)
           .states(EnumSet.allOf(OrderState.class))
           .and()
           .withCompositeStates()
               .withState(OrderState.PAYING, CompositeState.PAYMENT)
               .withStates(CompositeState.PAYMENT)
                   .initial(OrderState.PAYING)
                   .states(EnumSet.of(OrderState.PAYING, OrderState.PAID, OrderState.PAYMENT_FAILED));
}

(二)持久化狀態(tài)機上下文

在實際應用中,我們可能需要將狀態(tài)機的上下文(比如訂單對象)持久化,以便在應用重啟后能夠恢復狀態(tài)機的狀態(tài)。Spring 狀態(tài)機支持將狀態(tài)機的上下文持久化到數(shù)據(jù)庫或其他存儲介質(zhì)中,我們可以通過實現(xiàn) StateMachinePersist 接口來實現(xiàn)自定義的持久化邏輯。

(三)與外部系統(tǒng)交互

在狀態(tài)轉(zhuǎn)換過程中,可能需要與外部系統(tǒng)進行交互,比如調(diào)用支付接口、物流接口等。這時候,我們可以在動作中使用 Spring 的 RestTemplate 或其他客戶端來發(fā)起遠程調(diào)用,并處理調(diào)用結(jié)果。

@Bean
public Action<OrderState, OrderEvent> payAction() {
    return context -> {
        Order order = context.getMessage().getHeaders().get("order", Order.class);
        // 調(diào)用支付接口
        PaymentResponse response = restTemplate.postForObject(paymentUrl, order, PaymentResponse.class);
        if (response.isSuccess()) {
            order.setStatus(OrderState.PAID);
            order.setPaymentTime(new Date());
        } else {
            // 處理支付失敗,轉(zhuǎn)換到支付失敗狀態(tài)
            context.getStateMachine().transition(OrderEvent.PAYMENT_FAILED);
        }
    };
}

五、踩坑指南:使用 Spring 狀態(tài)機常見問題及解決辦法

(一)狀態(tài)轉(zhuǎn)換不生效

如果發(fā)現(xiàn)發(fā)送事件后狀態(tài)沒有轉(zhuǎn)換,首先要檢查配置的轉(zhuǎn)換規(guī)則是否正確,源狀態(tài)、目標狀態(tài)和事件是否匹配。其次,檢查守衛(wèi)條件是否返回 true,如果守衛(wèi)條件不滿足,轉(zhuǎn)換不會發(fā)生。另外,還要注意狀態(tài)機是否已經(jīng)啟動,在 Spring Boot 中,狀態(tài)機默認是自動啟動的,但如果在配置中關(guān)閉了自動啟動,需要手動調(diào)用 stateMachine.start() 方法。

(二)動作執(zhí)行順序問題

有時候,我們可能需要在狀態(tài)轉(zhuǎn)換的不同階段執(zhí)行不同的動作,比如在狀態(tài)轉(zhuǎn)換前執(zhí)行一些準備工作,在轉(zhuǎn)換后執(zhí)行一些清理工作。Spring 狀態(tài)機支持在轉(zhuǎn)換中定義多個動作,動作的執(zhí)行順序按照定義的順序進行。如果需要更精細地控制動作的執(zhí)行時機,可以使用 Action 接口的不同實現(xiàn),或者在配置中使用 beforeAction 和 afterAction 方法。

(三)狀態(tài)機上下文丟失

在使用狀態(tài)機時,上下文對象(比如訂單對象)通常是通過消息的頭部傳遞的。如果在狀態(tài)轉(zhuǎn)換過程中,上下文對象沒有正確傳遞,可能會導致動作或守衛(wèi)條件無法獲取到所需的數(shù)據(jù)。因此,在發(fā)送消息時,一定要確保上下文對象被正確設(shè)置到消息的頭部,并且在動作和守衛(wèi)條件中正確獲取。

(四)復雜狀態(tài)機調(diào)試困難

當狀態(tài)機配置比較復雜時,調(diào)試可能會比較困難。這時候,我們可以利用 Spring 狀態(tài)機提供的調(diào)試工具,比如打印狀態(tài)機的狀態(tài)和轉(zhuǎn)換信息,或者使用斷點調(diào)試來跟蹤狀態(tài)轉(zhuǎn)換的過程。另外,合理使用監(jiān)聽器來記錄狀態(tài)轉(zhuǎn)換的日志,也能幫助我們快速定位問題。

六、總結(jié):早用早受益,代碼優(yōu)雅不是夢

說了這么多,相信大家對 Spring 狀態(tài)機已經(jīng)有了一個比較清晰的認識了。使用 Spring 狀態(tài)機,我們可以將復雜的狀態(tài)邏輯從業(yè)務代碼中分離出來,通過配置的方式進行管理,讓代碼更加簡潔、優(yōu)雅、易維護。再也不用為了處理狀態(tài)邏輯而寫一堆惡心人的 if-else 了,媽媽再也不用擔心我的代碼會因為狀態(tài)判斷而出現(xiàn) bug 了。

當然,Spring 狀態(tài)機還有很多高級特性和應用場景等待我們?nèi)ヌ剿?,比如工作流引擎、有限狀態(tài)自動機等。只要我們合理運用,它就能成為我們開發(fā)過程中的得力助手,讓我們的代碼質(zhì)量更上一層樓。

責任編輯:武曉燕 來源: 石杉的架構(gòu)筆記
相關(guān)推薦

2020-10-15 10:38:35

C語言狀態(tài)模型

2025-10-29 07:38:45

2023-03-06 07:35:30

狀態(tài)機工具訂單狀態(tài)

2020-12-02 13:33:58

函數(shù)指針編程語言

2025-09-26 04:11:00

Spring狀態(tài)機業(yè)務流程

2010-06-18 12:38:38

UML狀態(tài)機視圖

2021-07-08 09:15:20

單片機編程狀態(tài)機編程語言

2010-06-18 13:25:44

UML狀態(tài)機視圖

2013-09-03 09:57:43

JavaScript有限狀態(tài)機

2025-08-28 01:12:00

狀態(tài)機系統(tǒng)編排

2021-06-05 05:11:52

代碼狀態(tài)機邏輯

2024-10-10 17:46:06

2024-04-16 09:21:59

Spring流轉(zhuǎn)狀態(tài)數(shù)據(jù)狀態(tài)處理

2010-07-08 13:03:31

UML狀態(tài)機圖

2011-06-24 16:09:24

Qt 動畫 狀態(tài)機

2022-03-06 19:57:50

狀態(tài)機easyfsm項目

2020-03-27 10:50:29

DSL 狀態(tài)機工具

2021-12-28 08:24:18

函數(shù)指針有限狀態(tài)機編程

2010-07-12 15:00:56

UML狀態(tài)機視圖

2021-08-19 09:00:00

微服務開發(fā)架構(gòu)
點贊
收藏

51CTO技術(shù)棧公眾號

精品在线观看一区二区| 精品自在线视频| 国产一区二区在线免费播放| 3d成人动漫在线| 国产精品亚洲专一区二区三区| 久久男人资源视频| 91视频免费看片| 国产精品毛片视频| 欧美日韩精品三区| 9久久9毛片又大又硬又粗| 91精品国产综合久久久久久豆腐| 国产精品一区专区| 国产精品成人一区| 日本天堂在线视频| 1024精品久久久久久久久| 亚洲成人激情在线观看| 在线观看av网页| 国产高清自产拍av在线| 亚洲婷婷国产精品电影人久久| 国产伦视频一区二区三区| 中文字幕一区二区在线视频| 日韩午夜av| 欧美精品在线观看| 国产免费美女视频| 暖暖日本在线观看| 久久久久久久综合| 成人免费看片网址| 国产精品久久777777换脸| 蜜桃视频一区| 91国产视频在线| 欧美日韩一级在线观看| 久久精品99久久无色码中文字幕| 日韩av影院在线观看| 中文字幕在线视频精品| 主播大秀视频在线观看一区二区| 精品美女久久久久久免费| 久久久99精品视频| 动漫一区在线| 日韩一区中文字幕| 国产一区二区三区免费播放| 日韩色在线观看| 黄色永久免费网站| 天天综合网站| 色一情一乱一乱一91av| 久久久一本二本三本| 97人人在线视频| 一区二区三区在线免费播放| 91xxx视频| 黄色网页在线观看| 综合色中文字幕| 天天做天天爱天天高潮| 黄色网页在线看| 亚洲欧美激情插| 在线观看污视频| 视频在线观看入口黄最新永久免费国产 | japanese国产在线观看| 久久看片网站| 国产精品入口夜色视频大尺度| 亚洲自拍一区在线观看| 久久久777| 国产精品久久综合av爱欲tv| av首页在线观看| 美女脱光内衣内裤视频久久网站 | 久久夜色精品国产噜噜av| 久久久久久高清| 你懂的视频在线| 国产校园另类小说区| 午夜精品亚洲一区二区三区嫩草 | 日韩av手机在线观看| 无码人妻一区二区三区免费| 日本欧美加勒比视频| 国产精品免费一区二区三区都可以| 亚洲免费视频二区| 国产一区二区美女| 国产免费一区二区三区| 五月婷中文字幕| 欧美国产禁国产网站cc| 精品国产三级a∨在线| 成人影音在线| 在线欧美小视频| 91 视频免费观看| caoporn成人免费视频在线| 亚洲精品不卡在线| 一级黄色录像毛片| 欧美精品aa| 7m精品福利视频导航| 久操视频在线免费观看| 精品一区二区三区在线观看| 成人午夜电影免费在线观看| 亚洲av成人无码网天堂| 国产精品久久久久aaaa樱花| 成人午夜视频免费观看| 欧美性suv| 欧美一区二区播放| 女尊高h男高潮呻吟| 91久久夜色精品国产按摩| 久久久久久成人精品| 国产精品成人无码| 国产99久久久精品| 亚洲高清在线观看一区| 草美女在线观看| 欧美色大人视频| 中国一级特黄录像播放| 色综合久久网| 欧美一级黄色网| 国产乱码精品一区二区| 91啪亚洲精品| 欧美视频在线第一页| 欧美xxx视频| 精品久久久三级丝袜| av免费播放网站| 午夜在线播放视频欧美| 亚洲精品欧美一区二区三区| 国产中文字幕在线视频| 亚洲午夜av在线| 99精品999| 国产午夜一区| 97婷婷大伊香蕉精品视频| 一区二区三区精彩视频| 久久久久国产精品人| 蜜臀av色欲a片无码精品一区| 久久亚洲资源中文字| 亚洲欧美福利视频| 国产真实的和子乱拍在线观看| 九色|91porny| 亚洲欧洲一区二区在线观看| 欧美成人性网| 国产婷婷97碰碰久久人人蜜臀| 2021亚洲天堂| 国产精品影音先锋| 偷拍盗摄高潮叫床对白清晰| 韩日精品一区| 亚洲欧洲国产精品| 亚洲精品男人的天堂| 97久久超碰国产精品电影| 男人添女荫道口女人有什么感觉| 婷婷激情成人| 日韩最新免费不卡| 在线视频 中文字幕| 欧美国产日韩a欧美在线观看 | 美女网站色91| 亚洲啪啪av| 国产a亚洲精品| 中文字幕国产精品久久| 中文字幕人妻一区二区三区视频 | 黄色a级片在线观看| 经典三级在线一区| 91免费视频黄| 日韩一区二区三区色| 久久夜色精品国产欧美乱| 国产精品高潮呻吟AV无码| 亚洲日本成人在线观看| 午夜免费一级片| 中文字幕亚洲综合久久五月天色无吗'' | 无码人妻一区二区三区免费| 久久精品视频网| 亚洲天堂av线| 91精品国偷自产在线电影 | 精品久久久中文字幕人妻| 亚洲另类在线视频| 大桥未久恸哭の女教师| 亚洲一区久久| 视频一区亚洲 | 视频一区在线播放| 欧美亚洲丝袜| 欧美一级做a| 美女999久久久精品视频| 性生交生活影碟片| 五月天网站亚洲| 亚洲色成人网站www永久四虎| 日韩av中文字幕一区二区| 亚洲欧洲日韩综合二区| 中文久久电影小说| 91国产精品91| 日本成人在线播放| 精品久久久三级丝袜| 久久中文字幕免费| 综合久久国产九一剧情麻豆| 超碰在线超碰在线| 亚洲九九精品| 亚洲日本欧美在线| 91久久偷偷做嫩草影院电| 欧美亚洲另类在线| 麻豆电影在线播放| 日韩成人在线免费观看| 亚洲视屏在线观看| 亚洲国产日韩综合久久精品| 一本加勒比北条麻妃| 激情综合色综合久久| 国内自拍在线观看| 66国产精品| 欧美日韩在线观看一区| 久久综合给合| 国产成人精品在线观看| 日本高清在线观看| 亚洲欧美中文字幕| www.激情五月| 欧美午夜精品久久久久久孕妇 | 欧美日韩国产系列| 欧美激情国产高清| 91浏览器在线观看| 国产精品久99| 国产精品无码网站| 国产伦精品一区二区三区免费迷 | 中老年在线免费视频| 久久伊人精品视频| 成人在线视频成人| 亚洲福利视频二区| 国产伦精品一区二区三区四区| 午夜伦理一区二区| 国产黄在线免费观看| 久久精品一区二区三区四区| 国产日韩视频一区| 国产尤物一区二区| av网站在线不卡| 亚洲一区二区成人| 免费人成自慰网站| 99精品在线| 亚洲精品乱码视频| 亚洲人成精品久久久| 国产伦精品一区二区三区照片| 精品视频一区二区三区| 国产精品美女网站| 欧美magnet| 欧美做爰性生交视频| 热色播在线视频| 久久久久久中文| 少妇视频在线| 欧美日本啪啪无遮挡网站| 日本激情视频在线观看| 亚洲人a成www在线影院| 五月天激情开心网| 亚洲国产精品久久精品怡红院| 国产三级精品在线观看| 欧美日韩高清一区二区不卡| 中文字幕第三页| 欧美午夜在线一二页| 无码免费一区二区三区| 色综合久久九月婷婷色综合| av大全在线观看| 欧美视频在线免费看| 91av在线免费视频| 天天综合日日夜夜精品| 日本熟妇毛耸耸xxxxxx| 午夜激情一区二区| 日韩毛片在线视频| 精品毛片三在线观看| 中文字幕黄色片| 在线视频亚洲一区| 在线观看免费高清视频| 欧美精品在线一区二区| 国产精品一区二区av白丝下载| 在线不卡免费欧美| www.黄色片| 亚洲激情小视频| 每日更新av在线播放| 亚洲人成电影网站色xx| 国产高清美女一级毛片久久| 中文字幕亚洲欧美日韩高清| 黄网站在线播放| 插插插亚洲综合网| 丰满诱人av在线播放| 91国产一区在线| 肉色欧美久久久久久久免费看| 国产精品国产福利国产秒拍| 成人免费一区| 亚洲aⅴ男人的天堂在线观看| 亚洲高清在线一区| 精品一区二区国产| 国产成人精品免费视| 宅男av一区二区三区| 欧美日韩一区二区国产| 人人妻人人添人人爽欧美一区| 亚洲欧美视频| 午夜精品中文字幕| 岛国精品在线播放| 第一次破处视频| 亚洲美女视频一区| 国产又黄又猛又粗又爽| 欧美日韩免费高清一区色橹橹| 国产丝袜在线视频| 日韩精品在线观看一区二区| 三区四区电影在线观看| 欧美激情第三页| 成人黄色免费网站| 国产精品手机在线| 清纯唯美综合亚洲| 六月婷婷在线视频| 青娱乐精品在线视频| 午夜诱惑痒痒网| 久久久综合视频| 永久av免费网站| 亚洲不卡一区二区三区| 日本中文字幕在线观看视频| 日韩美女主播在线视频一区二区三区 | 2020国产在线| 国产日韩欧美视频在线| 精品五月天堂| 干日本少妇视频| 玖玖国产精品视频| 国产性猛交96| 国产精品久久久久影院亚瑟| 国产成人无码精品久久久久| 欧美丰满一区二区免费视频| 青草久久伊人| 欧美黄色三级网站| 九九热这里有精品| 蜜桃麻豆www久久国产精品| 女主播福利一区| 亚洲36d大奶网| 久久久久久久久久久久久女国产乱 | 日韩国产专区| 精品久久久久久久久久中文字幕| 激情六月婷婷久久| 内射毛片内射国产夫妻| 色综合色狠狠综合色| 成人毛片视频免费看| 久久这里只有精品99| 99riav视频一区二区| 久久国产精品高清| 亚洲国产美女| 无码人妻aⅴ一区二区三区玉蒲团| 欧美激情一区二区三区蜜桃视频| 日本三级网站在线观看| 日韩一区二区电影在线| 黄视频在线观看网站| 国产精品高潮粉嫩av| 亚洲婷婷伊人| 丰满爆乳一区二区三区| 成人在线视频一区| 欧美极品视频在线观看| 欧美一级国产精品| 日本福利在线| 国产精品爽爽ⅴa在线观看| 国产精品一区2区3区| 日韩少妇内射免费播放18禁裸乳| 成人免费毛片片v| 国语对白一区二区| 欧美不卡在线视频| 国产后进白嫩翘臀在线观看视频| 99www免费人成精品| 欧美成人高清| 免费黄色a级片| 亚洲午夜电影网| 香蕉久久国产av一区二区| 69久久夜色精品国产69乱青草| 韩国精品福利一区二区三区| av免费观看国产| 99久久er热在这里只有精品15| 日韩黄色在线视频| 日韩黄色在线免费观看| 亚洲v.com| 日本一区免费| 久久激情五月婷婷| 五月天激情丁香| 欧美精品一区二区久久久| 成人bbav| 日本一区二区三区四区高清视频| 日本aⅴ免费视频一区二区三区| 成人黄色免费网址| 欧美日韩在线三级| 九七电影韩国女主播在线观看| 91在线免费视频| 亚洲高清网站| 美女爆乳18禁www久久久久久| 欧美影片第一页| 在线黄色网页| 国产一区不卡在线观看| 久久免费黄色| 免费成人深夜夜行网站| 欧美精品一区男女天堂| 亚洲三级欧美| 亚洲欧美日韩另类精品一区二区三区| 狠狠色狠狠色合久久伊人| 久久精品一区二区三| 精品一区电影国产| 日韩一级视频| 久久在线中文字幕| 久久久久国产精品麻豆ai换脸 | 偷拍中文亚洲欧美动漫| 亚洲最大免费| 成人av动漫在线| 国产在线一级片| 超碰97人人做人人爱少妇| 欧美人妖视频| 天天干天天色天天干| 欧美天堂在线观看| 尤物在线网址| 日韩一区免费观看| 大胆亚洲人体视频| 一二三四区在线| 91精品国产91久久久久久| 四虎成人av| 搡老熟女老女人一区二区| 欧美一区二区在线播放| 精品3atv在线视频| 国产青草视频在线观看| 中文字幕av一区二区三区免费看| 亚洲国产精品二区| 国产欧美日韩精品在线观看|