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

硬核 | 基于ASM實現Java類與接口的動態代理

開發 新聞
給大家分享一篇硬核的文章,基于ASM實現Java接口動態代理功能。

asm是一款編寫字節碼的框架,熟練使用可以加深對字節碼指令的掌握。

Java的動態代理?

Java動態代理是基于接口代理的,所以首先我們得定義一個公共接口。

現在代理用戶接口,實現登陸邏輯和來打印登錄的花費時間

public interface UserService {
boolean login(String username, String password);
}

再來看看Proxy的使用方法,newProxyInstance方法需要傳三個參數,第一個類加載器,第二個需要代理的接口數組,第三個參數是調用方法處理器,也是我們寫代理邏輯的需要實現的接口。

圖片

實現InvocationHandler,判斷傳入的username 和password是否等于admin,而且打印調用方法耗時。

public class UserServiceInvocationHandler implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException {
long start = System.currentTimeMillis();
System.out.println("invoke:" + proxy.getClass().getSimpleName() + "." + method.getName() + ":" + (System.currentTimeMillis() - start) + "ms");
return "admin".equals(args[0]) && "admin".equals(args[1]);
}
}

生成代理類

import java.lang.reflect.Proxy;
public class App {
public static void main(String[] args) {
UserService userServiceProxy = (UserService) Proxy.newProxyInstance(App.class.getClassLoader(), new Class[]{UserService.class}, new UserServiceInvocationHandler());
System.out.println(userServiceProxy.getClass());
System.out.println(userServiceProxy.login("admin", "admin"));
System.out.println(userServiceProxy.login("admin", "admin1"));
}
}

調用main方法,打印結果

圖片

使用ASM實現?

首先我們先看一下生成的代理類最終的樣子

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import proxy.ASMProxy;
import proxy.UserService;

public class $Proxy0 extends ASMProxy implements UserService {
public static Method _UserService_0 = Class.forName("proxy.UserService").getMethod("login", Class.forName("java.lang.String"), Class.forName("java.lang.String"));

public $Proxy0(InvocationHandler var1) {
super(var1);
}

public boolean login(String var1, String var2) throws Exception {
return (Boolean)super.h.invoke(this, _UserService_0, new Object[]{var1, var2});
}

}

三個要點:

  • InvocationHandler保存在ASMProxy中。
  • 要實現的接口方法Method使用靜態字段保存。
  • 實現接口方法內實際調用父類的InvocationHandler的invoke方法。

具體看看實現步驟

ASMProxy

package proxy;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.util.concurrent.atomic.AtomicInteger;

public class ASMProxy {
protected InvocationHandler h;
//代理類名計數器
private static final AtomicInteger PROXY_CNT = new AtomicInteger(0);
private static final String PROXY_CLASS_NAME_PRE = "$Proxy";

public ASMProxy(InvocationHandler var1) {
h = var1;
}

public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)throws Exception {
//生成代理類Class
Class<?> proxyClass = generate(interfaces);
Constructor<?> constructor = proxyClass.getConstructor(InvocationHandler.class);
return constructor.newInstance(h);
}

/**
* 生成代理類Class
*
* @param interfaces
* @return
*/
private static Class<?> generate(Class<?>[] interfaces) throws ClassNotFoundException {
String proxyClassName = PROXY_CLASS_NAME_PRE + PROXY_CNT.getAndIncrement();
byte[] codes = ASMProxyFactory.generateClass(interfaces, proxyClassName);
//使用自定義類加載器加載字節碼
ASMClassLoader asmClassLoader = new ASMClassLoader();
asmClassLoader.add(proxyClassName, codes);
return asmClassLoader.loadClass(proxyClassName);
}
}

ASMProxy的主要功能一個是作為代理類需要繼承的父類,接著提供一個和Proxy同樣的靜態方法newProxyInstance。newProxyInstance里面調用ASMProxyFactory生成字節碼二進制流,然后調用自定義的類加載器來生成Class。最后反射生成代理類的實例,返回對象。

ASMProxyFactory

接著看看最核心的部分,ASMProxyFactory是怎樣生成字節碼的,分幾個步驟:

  1. 創建初始化方法
  2. 聲明靜態字段
  3. 創建靜態方法
  4. 實現接口方法
package proxy;

import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.stream.Collectors;

public class ASMProxyFactory {
private static final Integer DEFAULT_NUM = 1;

public static byte[] generateClass(Class<?>[] interfaces, String proxyClassName) {
//創建一個ClassWriter對象,自動計算棧幀和局部變量表大小
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
//創建的java版本、訪問標志、類名、父類、接口
cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, proxyClassName, null, Type.getInternalName(ASMProxy.class), getInterfacesName(interfaces));
//創建<init>
createInit(cw);
//創建static
addStatic(cw, interfaces);
//創建<clinit>
addClinit(cw, interfaces, proxyClassName);
//實現接口方法
addInterfacesImpl(cw, interfaces, proxyClassName);
cw.visitEnd();
return cw.toByteArray();
}

private static String[] getInterfacesName(Class<?>[] interfaces) {
String[] interfacesName = new String[interfaces.length];
return Arrays.stream(interfaces).map(Type::getInternalName).collect(Collectors.toList()).toArray(interfacesName);
}

/**
* 創建init方法
* 調用父類的構造方法
* 0 aload_0
* 1 aload_1
* 2 invokespecial #1 <proxy/ASMProxy.<init> : (Ljava/lang/reflect/InvocationHandler;)V>
* 5 return
*
* @param cw
*/
private static void createInit(ClassWriter cw) {
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "(Ljava/lang/reflect/InvocationHandler;)V", null, null);
mv.visitCode();
//將this入棧
mv.visitVarInsn(Opcodes.ALOAD, 0);
//將參數入棧
mv.visitVarInsn(Opcodes.ALOAD, 1);
//調用父類初始化方法
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(ASMProxy.class), "<init>", "(Ljava/lang/reflect/InvocationHandler;)V", false);
// 返回
mv.visitInsn(Opcodes.RETURN);
mv.visitMaxs(2, 2);
mv.visitEnd();
}

/**
* 創建static字段
*
* @param cw
* @param interfaces
*/
private static void addStatic(ClassWriter cw, Class<?>[] interfaces) {
for (Class<?> anInterface : interfaces) {
for (int i = 0; i < anInterface.getMethods().length; i++) {
String methodName = "_" + anInterface.getSimpleName() + "_" + i;
cw.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, methodName, Type.getDescriptor(Method.class), null, null);
}
}
}

private static void addClinit(ClassWriter cw, Class<?>[] interfaces, String proxyClassName) {
//_UserService_0 = Class.forName("proxy.UserService").getMethod("login", String.class, String.class);
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_STATIC, "<clinit>", "()V", null, null);
mv.visitCode();
for (Class<?> anInterface : interfaces) {
for (int i = 0; i < anInterface.getMethods().length; i++) {
Method method = anInterface.getMethods()[i];
String methodName = "_" + anInterface.getSimpleName() + "_" + i;
mv.visitLdcInsn(anInterface.getName());
mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(Class.class), "forName", "(Ljava/lang/String;)Ljava/lang/Class;", false);
mv.visitLdcInsn(method.getName());
if (method.getParameterCount() == 0) {
mv.visitInsn(Opcodes.ACONST_NULL);
} else {
switch (method.getParameterCount()) {

case 1:
mv.visitInsn(Opcodes.ICONST_1);
break;
case 2:
mv.visitInsn(Opcodes.ICONST_2);
break;
case 3:
mv.visitInsn(Opcodes.ICONST_3);
break;
default:
mv.visitVarInsn(Opcodes.BIPUSH, method.getParameterCount());
break;
}
mv.visitTypeInsn(Opcodes.ANEWARRAY, Type.getInternalName(Class.class));
for (int paramIndex = 0; paramIndex < method.getParameterTypes().length; paramIndex++) {
Class<?> parameter = method.getParameterTypes()[paramIndex];
mv.visitInsn(Opcodes.DUP);
switch (paramIndex) {
case 0:
mv.visitInsn(Opcodes.ICONST_0);
break;
case 1:
mv.visitInsn(Opcodes.ICONST_1);
break;
case 2:
mv.visitInsn(Opcodes.ICONST_2);
break;
case 3:
mv.visitInsn(Opcodes.ICONST_3);
break;
default:
mv.visitVarInsn(Opcodes.BIPUSH, paramIndex);
break;
}
mv.visitLdcInsn(parameter.getName());
mv.visitMethodInsn(
Opcodes.INVOKESTATIC, Type.getInternalName(Class.class),
"forName",
"(Ljava/lang/String;)Ljava/lang/Class;",
false
);
mv.visitInsn(Opcodes.AASTORE);
}
}

// invokevirtual #13 <java/lang/Class.getMethod : (Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;>
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Class.class), "getMethod", "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;", false);
//putstatic #3 <proxy/$Proxy0._UserService_0 : Ljava/lang/reflect/Method;>
mv.visitFieldInsn(Opcodes.PUTSTATIC, proxyClassName, methodName, Type.getDescriptor(Method.class));
}
mv.visitInsn(Opcodes.RETURN);
}
mv.visitMaxs(DEFAULT_NUM, DEFAULT_NUM);
mv.visitEnd();
}

private static void addInterfacesImpl(ClassWriter cw, Class<?>[] interfaces, String proxyClassName) {
for (Class<?> anInterface : interfaces) {
for (int i = 0; i < anInterface.getMethods().length; i++) {
Method method = anInterface.getMethods()[i];
String methodName = "_" + anInterface.getSimpleName() + "_" + i;
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, method.getName(), Type.getMethodDescriptor(method), null, new String[]{Type.getInternalName(Exception.class)});
mv.visitCode();
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitFieldInsn(Opcodes.GETFIELD, Type.getInternalName(ASMProxy.class), "h", "Ljava/lang/reflect/InvocationHandler;");
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitFieldInsn(Opcodes.GETSTATIC, proxyClassName, methodName, Type.getDescriptor(Method.class));
//
switch (method.getParameterCount()) {
case 0:
mv.visitInsn(Opcodes.ICONST_0);
break;
case 1:
mv.visitInsn(Opcodes.ICONST_1);
break;
case 2:
mv.visitInsn(Opcodes.ICONST_2);
break;
case 3:
mv.visitInsn(Opcodes.ICONST_3);
break;
default:
mv.visitVarInsn(Opcodes.BIPUSH, method.getParameterCount());
break;
}
mv.visitTypeInsn(Opcodes.ANEWARRAY, Type.getInternalName(Object.class));
// * 12 dup
// * 13 iconst_0
// * 14 aload_1
// * 15 aastore
for (int paramIndex = 0; paramIndex < method.getParameterCount(); paramIndex++) {
mv.visitInsn(Opcodes.DUP);
switch (paramIndex) {
case 0:
mv.visitInsn(Opcodes.ICONST_0);
break;
case 1:
mv.visitInsn(Opcodes.ICONST_1);
break;
case 2:
mv.visitInsn(Opcodes.ICONST_2);
break;
case 3:
mv.visitInsn(Opcodes.ICONST_3);
break;
default:
mv.visitVarInsn(Opcodes.BIPUSH, paramIndex);
break;
}
mv.visitVarInsn(Opcodes.ALOAD, paramIndex + 1);
mv.visitInsn(Opcodes.AASTORE);
}
// * 20 invokeinterface #5 <java/lang/reflect/InvocationHandler.invoke : (Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;> count 4
// * 25 checkcast #6 <java/lang/Boolean>
// * 28 invokevirtual #7 <java/lang/Boolean.booleanValue : ()Z>
mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getInternalName(InvocationHandler.class), "invoke",
"(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;", true);
addReturn(mv, method.getReturnType());
// mv.visitFrame(Opcodes.F_FULL, 0, null, 0, null);
mv.visitMaxs(DEFAULT_NUM, DEFAULT_NUM);
mv.visitEnd();
}
}
}

//添加方法返回
private static void addReturn(MethodVisitor mv, Class<?> returnType) {
if (returnType.isAssignableFrom(Void.class)) {
mv.visitInsn(Opcodes.RETURN);
return;
}
if (returnType.isAssignableFrom(boolean.class)) {
//checkcast #6 <java/lang/Boolean>
// * 28 invokevirtual #7 <java/lang/Boolean.booleanValue : ()Z>
mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(Boolean.class));
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Boolean.class), "booleanValue", "()Z", false);
mv.visitInsn(Opcodes.IRETURN);
} else if (returnType.isAssignableFrom(int.class)) {
mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(Integer.class));
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Integer.class), "intValue", "()I", false);
mv.visitInsn(Opcodes.IRETURN);
} else if (returnType.isAssignableFrom(long.class)) {
mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(Long.class));
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Long.class), "longValue", "()J", false);
mv.visitInsn(Opcodes.JRETURN);
} else if (returnType.isAssignableFrom(short.class)) {
mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(Short.class));
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Short.class), "shortValue", "()S", false);
mv.visitInsn(Opcodes.IRETURN);
} else if (returnType.isAssignableFrom(byte.class)) {
mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(Byte.class));
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Byte.class), "byteValue", "()B", false);
mv.visitInsn(Opcodes.IRETURN);
} else if (returnType.isAssignableFrom(char.class)) {
mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(Character.class));
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Character.class), "charValue", "()C", false);
mv.visitInsn(Opcodes.IRETURN);
} else if (returnType.isAssignableFrom(float.class)) {
mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(Float.class));
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Float.class), "floatValue", "()F", false);
mv.visitInsn(Opcodes.FRETURN);
} else if (returnType.isAssignableFrom(double.class)) {
mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(Double.class));
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Double.class), "doubleValue", "()D", false);
mv.visitInsn(Opcodes.DRETURN);
} else {
mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(returnType));
mv.visitInsn(Opcodes.ARETURN);
}
}
}

ASMClassLoader

自定義類加載器,提供add方法,添加<類名、字節碼>映射關系。覆寫findClass方法,當類名能找到對應字節碼時,調用defineClass生成Class。

package proxy;

import java.util.HashMap;
import java.util.Map;

public class ASMClassLoader extends ClassLoader {
private final Map<String, byte[]> classMap = new HashMap<>();
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
if (classMap.containsKey(name)) {
byte[] bytes = classMap.get(name);
classMap.remove(name);
return defineClass(name, bytes, 0, bytes.length);
}
return super.findClass(name);
}
public void add(String name, byte[] bytes) {
classMap.put(name, bytes);
}
}

App

package proxy;

import java.lang.reflect.Proxy;

public class App {
public static void main(String[] args) throws Throwable {
System.out.println("Java動態代理===========================");
UserService userServiceProxy = (UserService) Proxy.newProxyInstance(App.class.getClassLoader(), new Class[]{UserService.class}, new UserServiceInvocationHandler());
System.out.println(userServiceProxy.getClass());
System.out.println(userServiceProxy.login("admin", "admin"));
System.out.println(userServiceProxy.login("admin", "admin1"));


System.out.println("ASM動態代理===========================");
UserService userServiceAsm = (UserService) ASMProxy.newProxyInstance(App.class.getClassLoader(), new Class[]{UserService.class}, new UserServiceInvocationHandler());
System.out.println(userServiceAsm.getClass());
System.out.println(userServiceAsm.login("admin", "admin"));
System.out.println(userServiceAsm.login("admin", "admin1"));
}
}

運行App:打印兩種代理方式的結果

圖片

責任編輯:張燕妮 來源: 冰河技術
相關推薦

2023-04-06 00:11:12

Java接口開發

2015-09-28 15:59:00

Java動態代理機制

2011-03-23 10:40:51

java代理模式

2022-02-22 22:44:46

接口源碼對象

2021-11-24 08:55:38

代理網關Netty

2022-04-02 07:52:47

DubboRPC調用動態代理

2017-05-11 21:30:01

Android動態代理ServiceHook

2009-12-28 15:45:22

動態網絡接入控制

2025-06-23 10:13:00

FutureTask線程開發

2025-02-27 00:32:35

2011-04-06 11:41:25

Java動態代理

2015-09-22 11:09:47

Java 8動態代理

2012-08-28 10:59:26

JavaJava動態代理Proxy

2021-07-06 06:39:22

Java靜態代理動態代理

2023-07-05 08:17:38

JDK動態代理接口

2020-12-29 05:34:00

動態代理

2009-06-22 15:10:00

java 編程AOP

2012-08-10 13:55:56

Java動態代理

2017-10-12 14:56:11

2023-02-24 07:42:30

Java動態代理
點贊
收藏

51CTO技術棧公眾號

亚洲天堂av图片| 成人日日夜夜| 精品久久国产| 欧美一区二区三区在线观看视频| 国产在线拍揄自揄拍无码| 精品人妻无码一区二区色欲产成人| 在线精品在线| 日韩中文字幕网| 日韩无码精品一区二区| 一区二区视频免费完整版观看| 最新不卡av在线| 国产精品久久久对白| 午夜精品久久久久久久蜜桃| 久久久久久影院| 国产视频久久久久| 四虎国产精品免费| **欧美日韩在线观看| 一区二区三区四区视频精品免费| 美女主播视频一区| 精品人妻一区二区三区麻豆91| 日韩一区欧美二区| 91精品国产免费久久久久久| 国产黄色片在线| 神马久久影院| 欧美哺乳videos| 国产精品嫩草影院8vv8| 周于希免费高清在线观看| 一卡二卡欧美日韩| 亚洲制服中文| 黄色电影免费在线看| 成人激情文学综合网| 91九色国产在线| 国产情侣小视频| 在线亚洲成人| 欧美激情在线播放| 国产午夜精品理论片在线| 久久99国内| 日韩精品在线免费播放| 午夜剧场免费看| 亚洲一区二区三区中文字幕在线观看| 欧美精品一卡二卡| 天天干天天干天天干天天干天天干| 美女搞黄视频在线观看| 亚洲图片自拍偷拍| 精品少妇人欧美激情在线观看| 嫩草在线视频| 国产精品高潮久久久久无| 日本一区二区高清视频| 性xxxxbbbb| gogogo免费视频观看亚洲一| 国产 高清 精品 在线 a| 国产视频在线观看免费 | 99热手机在线| 色8久久影院午夜场| 岛国视频午夜一区免费在线观看| 人妻av中文系列| av免费不卡国产观看| 五月天中文字幕一区二区| 日本手机在线视频| 成年女人在线看片| 欧美性极品少妇精品网站| 波多野结衣乳巨码无在线| 第一福利在线视频| 欧美性猛交xxxx黑人猛交| 天天摸天天碰天天添| 成人软件在线观看| 一本久久a久久精品亚洲| 99久久激情视频| 成人亚洲网站| 欧美一区二区啪啪| 91传媒理伦片在线观看| 卡通动漫国产精品| 亚洲色图综合网| 一本在线免费视频| 亚洲精品a级片| 久久久久久com| 四虎精品永久在线| 男女性色大片免费观看一区二区| 成人国产在线视频| 丰满肉嫩西川结衣av| 99久久亚洲一区二区三区青草| 蜜桃日韩视频| 求av网址在线观看| 亚洲色图欧洲色图婷婷| 国产 日韩 亚洲 欧美| 吞精囗交69激情欧美| 欧美精品久久久久久久久老牛影院| 亚洲女人在线观看| 五月国产精品| 久久精品精品电影网| 国产一级理论片| 日韩高清在线不卡| 91大片在线观看| 日本a一级在线免费播放| 欧美韩国日本不卡| 国产xxxx振车| 成人国产精品| 91麻豆精品91久久久久久清纯| 国产婷婷在线观看| 欧美少妇性xxxx| 欧美激情亚洲激情| 亚洲无码久久久久久久| 不卡的av在线| 中日韩在线视频| 天堂√8在线中文| 91精品国产91久久综合桃花| 大地资源二中文在线影视观看| 日韩欧美一区免费| 欧美一级视频在线观看| 国产情侣激情自拍| 久久久久9999亚洲精品| 久久久久久久久久伊人| 国产精品第一国产精品| 亚洲精品久久7777777| 国产老头老太做爰视频| 老司机精品福利视频| av一区和二区| 免费在线视频欧美| 欧美日韩在线一区| 无码人妻aⅴ一区二区三区玉蒲团| 精品久久影视| 久久久久久伊人| 国产精品久久久久久久久毛片| 久久综合色天天久久综合图片| 国产树林野战在线播放| 精品无人乱码一区二区三区 | 性欧美18—19sex性高清| 伊人成综合网| 国产日韩在线精品av| 国产在线视频网| 狠狠久久五月精品中文字幕| 亚洲911精品成人18网站| 亚洲h色精品| 成人福利视频网| av网站在线免费观看| 色拍拍在线精品视频8848| 国产xxxx视频| 99在线热播精品免费99热| 3d蒂法精品啪啪一区二区免费| 丝袜美腿美女被狂躁在线观看| 91福利在线导航| 亚洲精品成人无码熟妇在线| 亚洲裸体俱乐部裸体舞表演av| 国产精品v欧美精品v日韩| 日本中文字幕中出在线| 欧美一级高清片在线观看| 日本黄色片免费观看| 免费成人性网站| 亚洲一区三区| 亚洲人成777| 久久中文字幕视频| av免费在线观看不卡| 亚洲精品午夜久久久| 熟妇女人妻丰满少妇中文字幕| 欧美一区二区三区久久精品茉莉花 | 性欧美videos| 国产激情精品久久久第一区二区| 国产免费内射又粗又爽密桃视频| 日本在线视频一区二区三区| 欧美日本啪啪无遮挡网站| wwwxxxx国产| 精品久久久久久久久久国产| 制服丝袜第二页| 丝袜美腿亚洲综合| 一区二区三区欧美在线| 国产欧美视频在线| 国模私拍视频一区| 飘雪影院手机免费高清版在线观看| 日韩欧美在线免费| 91ts人妖另类精品系列| 国产高清视频一区| 可以在线看的av网站| 国产精品探花在线观看| 国产日韩换脸av一区在线观看| 99福利在线| 亚洲加勒比久久88色综合| 天堂网免费视频| 亚洲丝袜美腿综合| 久久久午夜精品福利内容| 久久久亚洲一区| 中文字幕成人一区| 在线视频亚洲欧美中文| 欧美诱惑福利视频| 麻豆传媒视频在线观看| 精品国产三级电影在线观看| 久久久久99精品成人片我成大片| 国产精品情趣视频| 亚洲一区二区三区四区av| 日韩在线卡一卡二| 777久久精品一区二区三区无码| 秋霞影视一区二区三区| 国产精品一区av| heyzo高清在线| 中文字幕日韩在线视频| 无码精品视频一区二区三区| 欧美日韩一级视频| 成人午夜视频精品一区| 国产精品国产精品国产专区不蜜 | 亚洲精品成人精品456| av无码一区二区三区| 久久国产日韩欧美精品| 无码粉嫩虎白一线天在线观看| 精品久久久久中文字幕小说| 国产激情一区二区三区在线观看| av在线播放一区| 97精品国产97久久久久久春色| 一区二区三区视频网站 | 免费高清完整在线观看| 日韩电影免费在线观看中文字幕 | 欧美一级二级视频| 性欧美视频videos6一9| 黄色成人影院| 一本一道久久a久久精品逆3p | 超碰成人福利| 成人久久一区二区三区| 成人免费福利| 55夜色66夜色国产精品视频| 色www永久免费视频首页在线| 中文字幕亚洲欧美日韩在线不卡 | 国产精品久久久久久福利一牛影视| asian性开放少妇pics| 国产成人亚洲综合a∨婷婷图片| 在线视频日韩一区 | 日本一二区免费| 久久亚洲欧洲| 国产精品专区在线| 欧美特黄一区| 国产日韩欧美大片| 亚洲v在线看| 一区二区三视频| 日韩国产一区二区| 日韩高清专区| 精品高清在线| 日韩欧美一区二区在线观看| 亚洲春色h网| 精品婷婷色一区二区三区蜜桃| 亚洲1区在线观看| 亚洲aa中文字幕| 国产一区二区久久久久| 91色p视频在线| 国产999精品在线观看| 91老司机精品视频| 国产日韩欧美中文在线| 成人亲热视频网站| 97久久中文字幕| 91在线观看欧美日韩| 粉嫩av国产一区二区三区| 亚洲一区二区三区sesese| 国产精品视频一区视频二区| 成人免费视频在线观看超级碰| 日韩av懂色| 91色在线视频| 亚洲精品一区二区三区中文字幕| av噜噜色噜噜久久| 精品人人人人| 国产午夜精品一区二区三区嫩草| 天天爱天天操天天干| 麻豆久久久久久| www.午夜av| 国产成人精品亚洲日本在线桃色 | 久久中文字幕视频| 怡红院在线观看| 久久久久久久久久久网站| 玖玖在线播放| 国产精品成av人在线视午夜片| 国产a亚洲精品| 亚洲va欧美va在线观看| 高清精品视频| 欧美日韩在线不卡一区| 日韩一区电影| 国产成人一区二区三区别| 国产情侣一区| 四季av一区二区| 国产精品影音先锋| 动漫精品一区二区三区| 国产精品美女久久久久高潮| 欧洲猛交xxxx乱大交3| 午夜精品福利在线| 日韩欧美国产另类| 日韩精品自拍偷拍| 日韩大片b站免费观看直播| 色综合亚洲精品激情狠狠| 在线中文字幕视频观看| 91大神福利视频在线| 欧美激情不卡| 国产在线精品一区| 日本成人小视频| 超碰成人免费在线| 奇米影视在线99精品| 久久久久无码国产精品一区李宗瑞 | 日本在线播放| 午夜精品福利电影| 成人黄色在线| 国产精品视频免费观看| 精品理论电影| 久久国产精品网| 美女视频黄免费的久久| 佐佐木明希电影| 中文av一区二区| 日韩精品乱码久久久久久| 欧美日韩亚洲综合一区二区三区| 亚洲国产福利视频| 中文字幕久精品免费视频| √最新版天堂资源网在线| 国产精品欧美日韩| 欧美三级午夜理伦三级在线观看 | 成人短视频在线观看| 久久久亚洲精选| 国产精品777777在线播放| 欧美专区一二三| 国产欧美不卡| 91福利视频免费观看| 国产精品久久久久久亚洲伦| 久久精品视频1| 精品国产乱码久久| 国产高清一区二区三区视频 | 日本在线视频一区二区三区| 亚洲国产午夜伦理片大全在线观看网站| 亚洲人成免费| 韩国三级在线播放| 亚洲免费伊人电影| 伊人影院中文字幕| 国产亚洲欧美aaaa| 惠美惠精品网| 免费亚洲一区二区| 99在线|亚洲一区二区| 污污免费在线观看| 亚洲精品日产精品乱码不卡| 91免费视频播放| 精品国产欧美一区二区三区成人| 欧美电影免费观看| 免费毛片一区二区三区久久久| 99pao成人国产永久免费视频| 日批免费观看视频| 一区二区视频在线| av一区二区三| 欧美精品在线网站| 亚洲视频一起| 日本在线视频www色| 国产精品主播直播| 久久久99精品| 亚洲精品一区二区三区精华液 | 欧美一级在线播放| 日本中文字幕在线一区| 欧美日韩在线一| 久久久综合网站| 天天干,天天干| 亚洲最新av在线| 欧美色片在线观看| 亚洲国产日韩美| 国产一区二区在线电影| 在线免费日韩av| 精品国免费一区二区三区| 国产盗摄精品一区二区酒店| 国产精品国色综合久久| 亚洲美女一区| 魔女鞋交玉足榨精调教| 欧美伊人精品成人久久综合97| av中文字幕在线| 91精品一区二区| 在线欧美福利| 国产全是老熟女太爽了| 欧美天天综合网| 超碰在线观看免费| 国产精品一区二区欧美黑人喷潮水| 亚洲成人资源| 成人激情五月天| 91麻豆精品91久久久久同性| 国产乱码在线| 日本一区二区三区四区在线观看| 蜜臀99久久精品久久久久久软件| 极品尤物一区二区| 日韩精品在线网站| 黄色在线免费观看网站| 欧美日韩另类综合| 黑人精品欧美一区二区蜜桃| 国产一级片播放| 伊人青青综合网站| jizz18欧美18| 亚洲欧美另类动漫| 亚洲一区二区偷拍精品| 理论在线观看| 亚洲最大成人网色| 久久大逼视频| 欧美三级小视频| 亚洲精品一区二三区不卡| 亚洲人成网站在线在线观看| www.av中文字幕| 国产精品福利电影一区二区三区四区| 高潮毛片7777777毛片| 国产成人一区二| 国产精品videosex极品| 美女久久久久久久久久| 日韩精品中文字幕在线不卡尤物| 91看片一区| 成人免费在线网| 中文字幕综合网| 人成在线免费视频| 成人在线看片| 久久成人麻豆午夜电影|