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

這款輕量級規則引擎,真香!

開發 前端
在一些輕量級的需要規則引擎的場景下,AviatorScript 真的太香了,尤其是它的擴展性,支持通過Java自定義函數,我甚至可以在腳本里查詢數據庫、查詢Redis、調用外部接口……這樣就可以像搭積木一樣搭建想要的功能。

簡介

AviatorScript 是一門高性能、輕量級寄宿于 JVM (包括 Android 平臺)之上的腳本語言。

它起源于2010年,作者對當時已有的一些產品不是很滿意,所以自己擼了一個,它是Groovy的一個定制化的子集。

圖片圖片

相比較一些傳統的規則引擎,比如Drools、Jess、JRules,它更加輕量級,而且性能更好,同時能力開放,擴展很方便。

我們來看(吹)看(吹)AviatorScript的特點:

  1. 它支持數字、字符串、正則表達式、布爾值等基本類型,并且可以使用所有 Java 運算符進行運算。
  2. 還有一個內置的東西叫做 bigint 和 decimal,可以處理超大整數和高精度運算。而且我們還可以通過運算符重載讓它們使用普通的算術運算符 +-*/。
  3. 語法非常齊全,可以用它來寫多行數據、條件語句、循環語句,還能處理詞法作用域和異常處理等等。
  4. 如果我們喜歡函數式編程,還有一個叫做 Sequence 抽象的東西,可以讓你更方便地處理集合。
  5. 還有一個輕量化的模塊系統,方便我們組織代碼。
  6. 如果我們需要調用 Java 方法,也沒問題,可以用多種方式方便地調用 Java 方法,還有一個完整的腳本 API可以讓你從 Java 調用腳本。
  7. 性能也是超出想象的好,如果使用 ASM 模式,它會直接將腳本翻譯成 JVM 字節碼,解釋模式還可以在 Android 等非標準 Java 平臺上運行。

AviatorScript可以用在各種場景,比如規則判斷和規則引擎、公式計算、動態腳本控制,甚至集合數據 ELT 等等。可以說相當全能了。

快速開始

AviatorScript 是一門寄生在 JVM (Hosted on the JVM)上的語言,類似 clojure/scala/kotlin 等等,我們從寫個Hello World開始。

  • 創建一個SpringBoot項目,引入依賴,這里選擇的是最新版本
<dependency>
            <groupId>com.googlecode.aviator</groupId>
            <artifactId>aviator</artifactId>
            <version>5.3.3</version>
        </dependency>

PS:可以看到aviator的groupId有一個googlecode,但是它和Google可沒什么關系,這是因為早期aviator托管在Google的一個開源項目托管平臺Google Code。

  • 在項目的resource目錄下創建一個目錄script,在script目錄下創建腳本hello.av
println("Hello, AviatorScript!");
  • 編寫一個單元測試,運行腳本
@Test
    void testHello() throws Exception {
        //獲取路徑
        ClassPathResource resource = new ClassPathResource("script/hello.av");
        String scriptPath = resource.getPath();
        //編譯
        Expression exp = AviatorEvaluator.getInstance().compileScript(scriptPath);
        //執行
        exp.execute();
    }

最后執行一下,就可以看到輸出:

Hello, AviatorScript!
  • 我們也可以直接把腳本定義成字符串,用compile()來進行編譯
@Test
    void testHelloStr() throws Exception {
        //定義腳本
        String script="println(\"Hello, AviatorScript!\");";
        //編譯
        Expression exp = AviatorEvaluator.getInstance().compile(script);
        //執行
        exp.execute();
    }

AviatorScript有一個Idea插件,支持直接編譯運行Aviator腳本,比較方便。

Aviator插件Aviator插件


但不足之處,這個插件已經不怎么維護了,只兼容到了Idea2021版本。

圖片Idea插件

AviatorScript腳本的運行,分為兩步,編譯和執行。

編譯執行編譯執行

編譯支持編譯腳本文件和腳本文本,分別使用compileScript和compile方法。

編譯產生的  Expression 對象,最終都是調用 execute() 方法執行。

這里有個重要能力,execute 方法可以接受一個變量列表組成的 map,來注入執行的上下文:

String expression = "a-(b-c) > 100";
        Expression compiledExp = AviatorEvaluator.compile(expression);
        //上下文
        double a=100.3,b=45,c= -199.100;
        Map<String, Object> cnotallow=new HashMap<>();
        context.put("a",a);
        context.put("b",b);
        context.put("c",c);
        //通過注入的上下文執行
        Boolean result = (Boolean) compiledExp.execute(context);
        System.out.println(result);

我們實現一些規則的判斷就是基于這個能力,把一些參數下上下文傳進去,然后進行邏輯判斷。

基本語法

我們在來看看AviatorScript的基本語法,它的語法相當簡潔,比較接近于數學表達式的形式。

基本類型及運算

AviatorScript 支持常見的類型,如數字、布爾值、字符串等等,同時將大整數、BigDecimal、正則表達式也作為一種基本類型來支持。

數字

AviatorScript 支持數字類型,包括整數和浮點數,以及高精度計算(BigDecimal)。數字類型可以進行各種算術運算。

整數和算術運算

整數類型,對應Java中的long類型,可以表示范圍為 -9223372036854774808 ~ 9223372036854774807 的整數。整數可以使用十進制或十六進制表示。

let a = 99;
let b = 0xFF;
let c = -99;

println(a + b); // 270
println(a / b); // 0
println(a - b + c); // -156
println(a + b * c); // -9801
println(a - (b - c)); // 198
println(a / b * b + a % b); // 99

整數可以進行加減乘除和取模運算。需要注意的是,整數相除的結果仍然是整數,遵循整數運算規則。可以使用括號來指定運算的優先級。

浮點數

浮點數類型對應Java中的double類型,表示雙精度 64 位浮點數。浮點數可以使用十進制或科學計數法表示。

let a = 1.34159265;
let b = 0.33333;
let c = 1e-2;

println(a + b); // 1.67492265
println(a - b); // 1.00826265
println(a * b); // 0.4471865500145
println(a / b); // 4.0257402772554
println(a + c); // 1.35159265

浮點數可以進行加減乘除運算,結果仍然為浮點數。

高精度計算(Decimal)

高精度計算使用 BigDecimal 類型,可以進行精確的數值計算,適用于貨幣運算或者物理公式運算的場景。可以通過在數字后面添加 "M" 后綴來表示 BigDecimal 類型。

let a = 1.34M;
let b = 0.333M;
let c = 2e-3M;

println(a + b); // 1.673M
println(a - b); // 1.007M
println(a * b); // 0.44622M
println(a / b); // 4.022022022M
println(a + c); // 1.342M

BigDecimal 類型可以進行加減乘除運算,結果仍然為 BigDecimal 類型。默認的運算精度是 MathContext.DECIMAL128,可以通過修改引擎配置項 Options.MATH_CONTEXT 來改變。

數字類型轉換

數字類型在運算時會自動進行類型轉換:

  • 單一類型參與的運算,結果仍然為該類型。
  • 多種類型參與的運算,按照 long -> bigint -> decimal -> double 的順序自動提升,結果為提升后的類型。

可以使用 long(x) 函數將數字強制轉換為 long 類型,使用 double(x) 函數將數字強制轉換為 double 類型。

let a = 1;
let b = 2;

println("a/b is " + a/b); // 0
println("a/double(b) is " + a/double(b)); // 0.5

a 和 b 都是 long 類型,它們相除的結果仍然是整數。使用 double(b) 將 b 轉換為 double 類型后,相除的結果為浮點數。

字符串

字符串類型由單引號或雙引號括起來的連續字符組成。可以使用 println 函數來打印字符串。

let a = "hello world";
println(a); // hello world

字符串的長度可以通過 string.length 函數獲取。

let a = "hello world";
println(string.length(a)); // 11

字符串可以通過 + 運算符進行拼接。

let a = "hello world";
let b = "AviatorScript";
println(a + ", " + b + "!" + 5); // hello world, AviatorScript!5

字符串還包括其他函數,如截取字符串 substring,都在 string 這個 namespace 下,具體見函數庫列表。

布爾類型和邏輯運算

布爾類型用于表示真和假,它只有兩個值 true 和 false 分別表示真值和假值。

比較運算如大于、小于可以產生布爾值:

println("3 > 1 is " + (3 > 1));  // 3 > 1 is true
println("3 >= 1 is " + (3 >= 1));  // 3 >= 1 is true
println("3 >= 3 is " + (3 >= 3));  // 3 >= 3 is true
println("3 < 1 is " + (3 < 1));  // 3 < 1 is false
println("3 <= 1 is " + (3 <= 1));  // 3 <= 1 is false
println("3 <= 3 is " + (3 <= 3));  // 3 <= 3 is true
println("3 == 1 is " + (3 == 1));  // 3 == 1 is false
println("3 != 1 is " + (3 != 1));  // 3 != 1 is true

上面演示了所有的邏輯運算符:

  • > 大于
  • >= 大于等于
  • < 小于
  • <= 小于等于
  • == 等于
  • != 不等于

基本語法

AviatorScript也支持條件語句和循環語句。

條件語句

AviatorScript 中的條件語句和其他語言沒有太大區別:

  • if
if(true) {
   println("in if body");
}
  • if-else
if(false){
   println("in if body");
} else {
   println("in else body");
}
  • if-elsif-else
let a = rand(1100);

if(a > 1000) {
  println("a is greater than 1000.");
} elsif (a > 100) {
  println("a is greater than 100.");
} elsif (a > 10) {
   println("a is greater than 10.");
} else {
   println("a is less than 10 ");
}

循環語句

AviatorScript提供了兩種循環語句:for和while。

for循環:遍歷集合

for ... in 語句通常用于遍歷一個集合,例如下面是遍歷 0 到 9 的數字

for i in range(0, 10) {
  println(i);
}

在這里,range(start, end) 函數用于創建一個整數集合,包括起始值 start,但不包括結束值 end。在循環迭代過程中,變量 i 綁定到集合中的每個元素,并執行大括號 {...} 中的代碼塊。

range 函數還可以接受第三個參數,表示遞增的步長大小(默認步長為 1)。例如,我們可以打印出0到9之間的偶數:

for i in range(0, 10, 2) {
  println(i);
}

for .. in 可以用于任何集合結構,比如數組、 java.util.List 、 java.util.Map 等等。

while循環

while 循環本質上是將條件語句與循環結合在一起。當條件為真時,不斷執行一段代碼塊,直到條件變為假。

例如,下面的示例中,變量 sum 從 1 開始,不斷累加自身,直到超過 1000 才停止,然后進行打印輸出:

let sum = 1;

while sum < 1000 {
  sum = sum + sum;
}

println(sum);

循環可以用這三個關鍵字結束——continue/break/return:

  • continue用于跳過當前迭代,繼續下一次迭代。
  • break用于跳出整個循環。
  • return用于中斷整個腳本(或函數)的執行并返回。

函數

我們再來看看AviatorScript一個非常重要的特性——函數。

函數

函數定義和調用

AviatorScript中使用fn語法來定義函數:

fn add(x, y) {
  return x + y;
}

three = add(1, 2);
println(three);  // 輸出:3

s = add('hello', ' world');
println(s);  // 輸出:hello world

我們這里通過fn關鍵字來定義了一個函數,函數名為add,它接受兩個參數x和y,并返回它們的和。

需要注意的是,AviatorScript是動態類型系統,不需要定義參數和返回值的類型,它會根據實際傳入和返回的值進行自動類型轉換。因此,我們可以使用字符串來調用add函數。

函數的返回值可以通過return語句來指定,也可以省略不寫。在函數體內,如果沒有明確的return語句,最后一個表達式的值將被作為返回值。

自定義函數

再來給大家介紹一個AviatorScript里非常好的特性,支持自定義函數,這給AviatorScript帶來了非常強的擴展性。

可以通過 java 代碼實現并往引擎中注入自定義函數,在 AviatorScript 中就可以使用,事實上所有的內置函數也是通過同樣的方式實現的:

public class TestAviator {

    public static void main(String[] args) {
        //通通創建一個AviatorEvaluator的實例
        AviatorEvaluatorInstance instance = AviatorEvaluator.getInstance();
        //注冊函數
        instance.addFunction(new AddFunction());
        //執行ab腳本,腳本里調用自定義函數
        Double result= (Double) instance.execute("add(1, 2)");
        //輸出結果
        System.out.println(result);
    }
}

/**
 * 實現AbstractFunction接口,就可以自定義函數
 */
class AddFunction extends AbstractFunction {

    /**
     * 函數調用
     * @param env 當前執行的上下文
     * @param arg1 第一個參數
     * @param arg2 第二個參數
     * @return 函數返回值
     */
    @Override
    public AviatorObject call(Map<String, Object> env,
                              AviatorObject arg1, AviatorObject arg2) {
        Number left = FunctionUtils.getNumberValue(arg1, env);
        Number right = FunctionUtils.getNumberValue(arg2, env);
        //將兩個參數進行相加
        return new AviatorDouble(left.doubleValue() + right.doubleValue());
    }

    /**
     * 函數的名稱
     * @return 函數名
     */
    public String getName() {
        return "add";
    }
}

我們看到:

  • 繼承AbstractFunction類,就可以自定義一個函數
  • 重寫call方法,就可以定義函數的邏輯,可以通過FunctionUtils獲取腳本傳遞的參數
  • 通過getName可以設置函數的名稱
  • 通過addFunction添加一個自定義函數類的實例,就可以注冊函數
  • 最后就可以在Aviator的腳本里編譯執行我們自定義的函數

好了,關于AviatorScript的語法我們就不過多介紹了,大家可以直接查看官方文檔[1],可讀性相當不錯。

接下來我們就來看看AviatorScript的實際應用,看看它到底怎么提升項目的靈活性。

實戰案例

標題帶了規則引擎,在我們的項目里也主要是拿AviatorScript作為規則引擎使用——我們可以把AviatorScript的腳本維護在配置中心或者數據庫,進行動態地維護,這樣一來,一些規則的修改,就不用大動干戈地去修改代碼,這樣就更加方便和靈活了。

圖片圖片

Aviator應用

客戶端版本控制

在日常的開發中,我們很多時候可能面臨這樣的情況,兼容客戶端的版本,尤其是Android和iPhone,有些功能是低版本不支持的,或者說有些功能到了高版本就廢棄掉,這時候如果硬編碼去兼容就很麻煩,那么就可以考慮使用規則腳本的方式。

  • 自定義版本比較函數:AviatorScript沒有內置版本比較函數,但是可以利用它的自定義函數特性,自己定義一個版本比較函數
class VersionFunction extends AbstractFunction {

        @Override
        public String getName() {
            return "compareVersion";
        }

        @Override
        public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2) {
            // 獲取版本
            String version1 = FunctionUtils.getStringValue(arg1, env);
            String version2 = FunctionUtils.getStringValue(arg2, env);
            int n = version1.length(), m = version2.length();
            int i = 0, j = 0;
            while (i < n || j < m) {
                int x = 0;
                for (; i < n && version1.charAt(i) != '.'; ++i) {
                    x = x * 10 + version1.charAt(i) - '0';
                }
                ++i; // 跳過點號
                int y = 0;
                for (; j < m && version2.charAt(j) != '.'; ++j) {
                    y = y * 10 + version2.charAt(j) - '0';
                }
                ++j; // 跳過點號
                if (x != y) {
                    return x > y ? new AviatorBigInt(1) : new AviatorBigInt(-1);
                }
            }
            return new AviatorBigInt(0);
        }
    }
  • 注冊自定義函數:為了方便使用各種自定義函數,我們一般定義一個單例的AviatorEvaluatorInstance,把它注冊成Bean
@Bean
    public AviatorEvaluatorInstance aviatorEvaluatorInstance() {
        AviatorEvaluatorInstance instance = AviatorEvaluator.getInstance();
        // 默認開啟緩存
        instance.setCachedExpressionByDefault(true);
        // 使用LRU緩存,最大值為100個。
        instance.useLRUExpressionCache(100);
        // 注冊內置函數,版本比較函數。
        instance.addFunction(new VersionFunction());
    }
  • 在代碼里傳遞上下文:接下來,就可以在業務代碼里將一些參數放進執行上下文,然然后進行編譯執行,注意編譯的時候最好要開啟緩存,這樣效率會高很多
/**
     * 
     * @param device 設備
     * @param version 版本
     * @param rule 規則腳本
     * @return
     */
    public boolean filter(String device,String version,String rule){
        // 執行參數
        Map<String, Object> env = new HashMap<>();
        env.put("device", device);
        //編譯腳本
        Expression expression = aviatorEvaluatorInstance.compile(DigestUtils.md5DigestAsHex(rule.getBytes()), rule, true);
        //執行腳本
        boolean isMatch = (boolean) expression.execute(env);
        return isMatch;
    }
  • 編寫腳本:接下來就可以編寫和維護對應的規則腳本,這些規則腳本通常放在在配置中心或者數據庫,方便進行動態變更
if(device==bil){
    return false;
}

## 控制android的版本
if (device=="Android" && compareVersion(version,"1.38.1")<0){
    return false;
}

return true;

這樣一來,假如某天,客戶端Bug或者產品原因,需要修改客戶端和客戶端的版本控制,直接修改腳本就好了。

甚至我們可以在env里放進更多參數,比如uid,可以實現簡單的黑白名單。

我們的自定義函數除了這種簡單的比較版本,我們還可以放一些復雜的邏輯,比如判斷是否新用戶等等。

營銷活動規則

假如現在我們的運營希望進行一場營銷活動,對用戶進行一定的支付優惠,最開始的一版活動規則:

  • 滿1000減200,滿500減100

這個好寫,一頓if-else就完事了。

但是沒過幾天,又改了活動規則:

  • 首單用戶統一減20

好,啪啪改代碼。

又過去幾天,活動規則又改了:

  • 隨機優惠不同金額

為了一些多變的營銷規則,大動干戈,不停修改代碼,耗時費力,那么不如用規則腳本實現:

  • 定義腳本
if (amount>=100){
    return 200;
}elsif(amount>=500){
    return 100;
}else{
    return 0;
}
  • 業務代碼調用
public BigDecimal getDiscount(BigDecimal amount,String rule){
        // 執行規則并計算最終價格
        Map<String, Object> env = new HashMap<>();
        env.put("amount", amount);
        Expression expression = aviatorEvaluatorInstance.compile(DigestUtils.md5DigestAsHex(rule.getBytes()), rule, true);
        return  (BigDecimal) expression.execute();
    }

接下來,再發生營銷規則變更,就可以少量開發(自定義函數,比如判斷首單用戶),并且可以組件化地維護營銷規則。

訂單風控規則

Aviator我在訂單風控里應用也很香,風控的規則調整是相當頻繁的,比如一個電商網站,常常要根據交易的爭議率、交易表現等等,來收緊和放松風控規則,這就要求我們能對一風控規則進行快速地配置變更。

例如,根據訂單金額、客戶評級、收貨地址等屬性,自動判斷是否有風險并觸發相應的風控操作。

  • 規則腳本
if (amount>=1000 || rating <= 2){
    return "High";
}elsif(amount >= 500 || rating<=4){
    return "Mid";
}else{
    return "Low";
}
  • 代碼調用:這里只是簡單返回了一個風控等級,其實可以通過Map的方式返回多個參數。
public String riskLevel(BigDecimal amount,String rating,String rule){
        // 執行規則并計算最終價格
        Map<String, Object> env = new HashMap<>();
        env.put("amount", amount);
        env.put("rating", rating);
        Expression expression = aviatorEvaluatorInstance.compile(DigestUtils.md5DigestAsHex(rule.getBytes()), rule, true);
        return  (String) expression.execute();
    }

上面隨手列出了幾個簡單的例子,AviatorScript 還可以用在一些審批流程、事件處理、數據質量管理等等場景……

在一些輕量級的需要規則引擎的場景下,AviatorScript 真的太香了,尤其是它的擴展性,支持通過Java自定義函數,我甚至可以在腳本里查詢數據庫、查詢Redis、調用外部接口……這樣就可以像搭積木一樣搭建想要的功能。

總結

這一期給大家分享了一款輕量級的規則腳本語言AviatorScript,它的語法豐富,但是很輕量,并且支持非常靈活的擴展,在項目中使用可以有效提高業務的靈活性,降低開發的工作量。

  1. 本來這期想淺淺盤點一下AviatorScript的設計實現,結果發現越盤越深,所以就單獨拆出來,放在下一期了,敬請期待。
責任編輯:武曉燕 來源: 三分惡
相關推薦

2025-08-01 09:38:00

2025-05-13 04:15:00

2024-11-13 16:32:21

aviatorJava表達式引擎

2023-11-01 11:04:12

Javaaviator

2025-02-19 09:55:39

2025-06-23 00:00:05

2022-03-22 09:20:57

應用線程池技術

2022-09-05 09:37:38

Linux發行版

2024-02-26 07:46:54

Markdown語法標記語言有序列表

2019-05-07 14:42:03

深度學習編程人工智能

2025-06-09 02:11:00

2025-03-18 14:33:14

2025-03-05 09:30:00

小模型CIO智能化轉型

2009-07-17 14:38:51

輕量級Swing組件

2009-07-14 18:05:28

輕量級Swing組件

2016-10-14 16:35:39

2009-09-11 08:26:49

Linux系統CRUX 2.6Linux

2023-06-27 16:42:18

Tinygrad深度學習工具

2021-03-02 09:35:33

Python循環開發

2023-09-14 09:31:21

Docker容器
點贊
收藏

51CTO技術棧公眾號

免费久久99精品国产| 亚洲免费专区| 亚洲第一成人在线| 精品视频一区二区三区四区| 国产真人无遮挡作爱免费视频| 成人综合久久| 欧美α欧美αv大片| 日韩欧美精品在线观看视频| 人人干在线视频| 国产.精品.日韩.另类.中文.在线.播放| 97激碰免费视频| 亚洲天堂av中文字幕| 国产欧美三级电影| 欧美性色综合网| 久操网在线观看| 一本一道波多野毛片中文在线| 成人国产免费视频| 国产欧美在线视频| 青青青国产在线| 欧美日韩四区| 国产一区二区三区直播精品电影| 亚洲成年人av| 五月天色综合| 欧美亚洲动漫精品| 看av免费毛片手机播放| 在线播放免费av| 中文字幕在线观看一区二区| 欧美精品人人做人人爱视频| 亚洲不卡免费视频| 美女网站色91| 国产aⅴ夜夜欢一区二区三区| 国产亚洲成人精品| 国产精品97| 在线成人免费网站| 90岁老太婆乱淫| 国产色噜噜噜91在线精品 | 欧美国产精品专区| 欧美凹凸一区二区三区视频 | 亚洲天堂视频在线观看| fc2成人免费视频| 亚洲一区二区三区免费| 欧美一区二区美女| 午夜xxxxx| 91视频亚洲| 在线观看91av| 婷婷激情综合五月天| 欧美aaaaaa| 欧美色图在线观看| 在线免费视频一区| 欧美特黄色片| 777精品伊人久久久久大香线蕉| 邪恶网站在线观看| 日韩三区四区| 91精品国产综合久久精品app| caoporm在线视频| 偷拍自拍亚洲| 日韩免费高清av| 国产精品日日摸夜夜爽| 91精品国产乱码久久久竹菊| 亚洲аv电影天堂网| 亚洲欧洲国产视频| 激情视频极品美女日韩| 亚洲精品久久视频| 亚洲一区二区乱码| japanese国产精品| xxxx欧美18另类的高清| 全程偷拍露脸中年夫妇| 亚洲国产日本| 日韩av色综合| 一级黄色a视频| 国产麻豆精品久久一二三| 97人人干人人| 少妇av在线播放| 久久久久久久久久电影| 亚洲视频电影| 女囚岛在线观看| 午夜成人免费电影| 少妇激情一区二区三区| 亚洲ww精品| 精品久久一区二区三区| 亚洲狠狠婷婷综合久久久久图片| 精品国产乱码| 欧美成人在线网站| 免费看日批视频| 久久91精品国产91久久小草| 国产一区二区在线网站 | 久久亚洲精品一区二区| 麻豆changesxxx国产| 亚洲综合不卡| 成人性生交xxxxx网站| 色窝窝无码一区二区三区| 国产欧美日本一区二区三区| www.18av.com| 欧美理论影院| 欧美sm极限捆绑bd| 天天干天天舔天天操| 国产精品啊v在线| 日本午夜在线亚洲.国产| 国产情侣一区二区| 久久亚洲精华国产精华液| 天天成人综合网| 亚洲人体视频| 日韩欧美电影一区| 天天操天天干天天操天天干| 极品av少妇一区二区| 国产精品三级美女白浆呻吟| 黄色美女一级片| 亚洲日穴在线视频| 激情视频综合网| 国内自拍欧美| 久久69精品久久久久久国产越南| 国产精品久久久久久人| 国产不卡在线视频| 亚洲欧洲一二三| 国产精品迅雷| 亚洲高清av在线| 日韩成人短视频| 日韩av午夜在线观看| 精品在线观看一区二区| 青草在线视频| 91精品综合久久久久久| 欧美人妻一区二区三区| 99成人在线| 国产91亚洲精品一区二区三区| 亚乱亚乱亚洲乱妇| 色婷婷综合久色| 成人网站免费观看| 亚洲国内自拍| 国产精品18毛片一区二区| 免费黄色电影在线观看| 欧美日韩一级视频| 亚洲天堂岛国片| 日韩国产欧美三级| 欧美精品在线一区| 国产高清不卡| 亚洲欧美国产精品专区久久 | 大又大又粗又硬又爽少妇毛片 | 奇门遁甲1982国语版免费观看高清| 亚洲av无码乱码在线观看性色| 中文字幕日韩av资源站| 午夜精品久久久久久久99热影院| 凹凸成人精品亚洲精品密奴| 国产成人一区二| 国产在线你懂得| 在线免费一区三区| 性欧美精品男男| 日韩电影在线免费观看| 日韩影院一区| 国产精品原创视频| 日韩中文字幕在线看| 一级片在线观看视频| 椎名由奈av一区二区三区| 日韩av一卡二卡三卡| 亚洲综合婷婷| y111111国产精品久久婷婷| 色网在线观看| 日韩电影中文字幕av| 国产精品视频一区在线观看| 久久精品人人做人人综合| 日本熟妇人妻中出| 久久久综合色| 97se亚洲综合| а√在线天堂官网| 国产亚洲综合久久| 国产精品女同一区二区| 一区二区三区**美女毛片| 国产一线在线观看| 久久精品观看| 亚洲欧洲日韩精品| 操欧美女人视频| 欧美有码在线观看| 天天在线视频色| 日韩精品中文字幕一区| 一级片中文字幕| 日本一区二区免费在线| 性生活在线视频| 亚洲精选在线| 亚洲成人在线视频网站| 欧美黄色一级| 26uuu亚洲伊人春色| a视频网址在线观看| 日韩一区二区中文字幕| 黄色一级片免费看| 国产精品久久久久婷婷二区次| 日本特黄在线观看| 亚洲一区观看| 日韩第一页在线观看| 农村少妇一区二区三区四区五区 | 天堂免费在线视频| 亚洲免费观看在线视频| 亚洲av无码国产精品久久| 精品一区免费av| 国产视频一视频二| 国产精品精品| 欧美日韩一区二区视频在线观看| 国产精品成人3p一区二区三区| 午夜精品久久久久久99热软件| 波多野结衣在线影院| 精品精品国产高清a毛片牛牛 | 日本伊人精品一区二区三区观看方式| 强伦女教师2:伦理在线观看| 婷婷成人影院| 91精品国产综合久久久久久丝袜 | 91精品蜜臀在线一区尤物| 免费看日韩毛片| 亚洲欧美视频一区| 国产aⅴ激情无码久久久无码| 国产成人精品影视| 亚洲一区在线不卡| 一区二区精品| www.在线观看av| 亚洲色图国产| 婷婷久久五月天| 日韩有码中文字幕在线| 97超碰人人看人人 | 国产另类自拍| 9.1麻豆精品| 国产精品入口免费视| av日韩亚洲| 午夜欧美大片免费观看| 超碰在线观看免费版| 色综合伊人色综合网站| 日本中文字幕一区二区有码在线| 日韩一区二区三区视频在线观看| 老熟妇一区二区三区啪啪| 色综合天天天天做夜夜夜夜做| 国产中文字幕免费| 一区二区三区小说| 色欲人妻综合网| 中文字幕在线观看一区| gv天堂gv无码男同在线观看| 久久久久一区二区三区四区| 91黄色免费视频| 成人短视频下载| 99热超碰在线| 丰满少妇久久久久久久| 又大又长粗又爽又黄少妇视频| 国内久久婷婷综合| www.污污视频| 韩国午夜理伦三级不卡影院| 国产成人美女视频| 激情综合色综合久久| mm131国产精品| 久久99精品国产| 加勒比av中文字幕| 精品一二三四在线| 亚洲一区二区图片| 国产成人免费视频一区| 18禁一区二区三区| 成人精品视频一区| 好男人香蕉影院| 26uuu精品一区二区| 亚洲人成人无码网www国产| 久久精品一区四区| 极品人妻videosss人妻| 国产精品理论片| 国产探花在线免费观看| 亚洲在线成人精品| 午夜毛片在线观看| 日本久久一区二区三区| 在线视频 91| 日韩一区二区三区视频| 日本精品999| 亚洲午夜精品久久久久久性色| 在线观看的av| 欧美精品中文字幕一区| 91色在线看| 日本成熟性欧美| 欧美黑粗硬大| 成人欧美视频在线| 欧美猛男同性videos| 亚洲午夜高清视频| 亚洲性色视频| 日本熟妇人妻中出| 国产高清在线精品| 在线 丝袜 欧美 日韩 制服| 国产精品网曝门| 毛片a片免费观看| 色悠悠久久综合| 国产成人精品一区二三区四区五区 | 一区在线观看视频| jizz国产免费| 欧美综合色免费| av无码精品一区二区三区宅噜噜| 亚洲精品大尺度| 天天影视久久综合| 69av在线播放| 粉嫩av国产一区二区三区| 国产主播福利在线| 国产精品色婷婷| 青娱乐av在线| 色婷婷av一区二区三区软件| 国产又粗又黄又爽视频| 亚洲成人激情在线| aaa在线观看| 久久久久久久久久久免费精品| 成年美女黄网站色大片不卡| 91嫩草在线视频| 亚洲黄页在线观看| 波多野结衣 作品| 日韩精品免费视频人成| 337p日本欧洲亚洲大胆张筱雨 | 91夜夜揉人人捏人人添红杏| 日韩三级视频| wwwjizzjizzcom| 奇米色一区二区| 国产亚洲色婷婷久久99精品91| 亚洲欧洲精品一区二区精品久久久| 精品久久免费视频| 91麻豆精品91久久久久同性| 国产高清视频免费最新在线| 久久久久久久香蕉网| 亚洲视频自拍| 少妇精品久久久久久久久久| 亚洲欧洲另类| 日本中文字幕有码| 亚洲婷婷国产精品电影人久久| 丰满人妻老熟妇伦人精品| 精品奇米国产一区二区三区| 免费在线视频欧美| 国产精品久久久久久久久久ktv| 私拍精品福利视频在线一区| 中文精品无码中文字幕无码专区| 久久精品99久久久| 69视频在线观看免费| 欧美性猛交xxxx免费看久久久| 日韩一卡二卡在线| 欧美高清视频一区二区| 国产aa精品| 香蕉视频在线网址| 久久丁香综合五月国产三级网站| 男人操女人动态图| 欧美日韩国产在线| 四虎在线视频| 91sa在线看| 色婷婷久久久| 男人靠女人免费视频网站 | 日本成人午夜影院| 色婷婷综合久久久久中文一区二区 | 日日夜夜精品网站| 日韩一区欧美二区| 久久中文字幕精品| 欧美日韩一二区| 日本中文字幕在线播放| 国产日韩av高清| 四季av一区二区凹凸精品| 福利片一区二区三区| 日韩理论片在线| 国产xxxxxx| 久久久久久久999| 欧美变态网站| 欧美 激情 在线| 国产欧美日韩在线视频| 在线中文字幕网站| 久久伊人91精品综合网站| 亚洲不卡在线| 少妇高潮毛片色欲ava片| 99精品国产一区二区三区不卡| 久久亚洲天堂网| 国产亚洲欧美一区| 24小时成人在线视频| 日本福利视频网站| 97久久精品人人爽人人爽蜜臀 | 日本强好片久久久久久aaa| 亚洲综合第一区| 欧美一区二区美女| 少妇淫片在线影院| 婷婷四房综合激情五月| 国产麻豆午夜三级精品| 亚洲国产精一区二区三区性色| 亚洲美女av黄| 亚洲男人在线| 久久成人福利视频| 国产视频一区不卡| 国产视频第一页| 久久久久久欧美| 国产探花在线精品| 国产又粗又猛大又黄又爽| 天天综合网 天天综合色| 国产高清自拍视频在线观看| 成人网在线免费观看| 亚洲精品影院在线观看| 国产黄色大片免费看| 欧美变态凌虐bdsm| 欧美日韩精品免费观看视完整| 综合久久国产| 99re66热这里只有精品3直播| 特级西西444www大胆免费看| 欧美丰满少妇xxxxx做受| 久操国产精品| 色诱av手机版| 欧美三级三级三级| 国产精品13p| 亚洲午夜在线观看| 99国产精品久久久久久久久久| 中文字幕人妻互换av久久| 欧美激情亚洲另类| 97国产成人高清在线观看| 9.1成人看片| 日韩欧美一区二区在线视频|