精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

日本成人黄色| 91av视频在线播放| 天堂va欧美va亚洲va老司机| 高清电影在线免费观看| 久久久久久9999| 国产一区二区在线免费视频| 亚欧洲精品在线视频| 国产一区二区精品久| 91精品免费观看| koreanbj精品视频一区| 在线观看免费网站黄| 成人在线综合网| 国产精品日韩久久久久| 亚洲国产综合久久| 三级电影一区| 亚洲精品在线91| gogo亚洲国模私拍人体| 草民电影神马电影一区二区| 亚洲一区二区三区在线| 亚洲三区四区| 四虎国产精品永远| 国产风韵犹存在线视精品| 国产盗摄xxxx视频xxx69| 欧美人妻一区二区| 99re6这里只有精品| 国产视频综合在线| 国产免费a级片| 少妇精品视频在线观看| 日韩欧美在线免费观看| 91精品一区二区三区四区| 国产区视频在线播放| aaa欧美色吧激情视频| 亚洲精品欧美日韩| 亚洲无码久久久久| 日韩成人一区二区三区在线观看| 久久琪琪电影院| 欧美成人精品一区二区免费看片| 青青一区二区三区| 亚洲网站在线看| 国产精品久久久久久在线观看| gogo大尺度成人免费视频| 色视频成人在线观看免| 波多野结衣乳巨码无在线| 欧美videos另类精品| 日韩理论片网站| 一区中文字幕在线观看| 888av在线| 国产精品网站一区| 亚洲欧洲精品一区二区| 99re热久久这里只有精品34| 国产午夜三级一区二区三| 欧美高清视频一区| 久草视频在线看| 久久精品视频免费| 欧美日韩一区二区三| 国产在线日本| 欧美激情在线一区二区| 亚洲午夜精品久久久中文影院av| 成人在线观看一区| 国产精品日日摸夜夜摸av| 午夜精品一区二区三区在线观看| 成年人在线视频免费观看| 国产亚洲短视频| 天堂社区 天堂综合网 天堂资源最新版 | 一区精品久久| 国语对白做受69| 五月天婷婷久久| 久久久久在线| 国产精品一区二区久久久| 一级黄色片在线播放| 国产一区二区伦理| 国产成人精品福利一区二区三区| 无码精品视频一区二区三区| av电影在线观看完整版一区二区| 免费国产一区二区| 日韩黄色影院| 亚洲一区二区欧美激情| 亚洲午夜精品久久久久久人妖| 国产日韩电影| 欧美日韩综合在线| 天美一区二区三区| 欧美a大片欧美片| 在线看欧美日韩| 麻豆成人在线视频| 男女精品网站| **亚洲第一综合导航网站| 噜噜噜久久,亚洲精品国产品| av亚洲精华国产精华精| 亚洲 国产 日韩 综合一区| 99热国产在线| 色综合天天在线| 两性午夜免费视频| 欧美调教视频| 精品国偷自产在线| 欧美精品亚洲精品日韩精品| 久久国内精品自在自线400部| 99热99热| 91激情在线| 欧美日韩免费网站| 色天使在线观看| 任我爽精品视频在线播放| 日韩在线精品视频| 日韩黄色在线播放| 国产91在线看| 亚洲精品视频一二三| 白白色在线观看| 4438成人网| 亚洲自拍偷拍图| 影音先锋亚洲精品| 成人激情av在线| 九色在线观看| 亚洲高清一区二区三区| 999在线精品视频| 精品在线91| 国内揄拍国内精品| 国产三级在线观看视频| 中文字幕欧美激情| 欧美网站免费观看| 国产96在线亚洲| 久久这里有精品| 中文字幕91爱爱| 久久色.com| 国产青青在线视频| 在线精品自拍| 日韩在线观看精品| 国产情侣呻吟对白高潮| www国产成人免费观看视频 深夜成人网| 日本黄色播放器| 不卡亚洲精品| 欲色天天网综合久久| 99久久久久久久久| 91在线视频在线| 国产69精品久久久久久久| 色妞ww精品视频7777| 日韩一级黄色av| 91福利在线观看视频| 欧美国产丝袜视频| 嫩草影院国产精品| 精品国产一区二区三区小蝌蚪| **欧美日韩vr在线| 香蕉视频网站在线| 午夜精品123| 中文成人无字幕乱码精品区| 亚洲黄色成人| 好看的日韩精品| 欧美xxxhd| 国产婷婷97碰碰久久人人蜜臀| 日本少妇裸体做爰| 99久久国产综合精品女不卡| 人人妻人人澡人人爽欧美一区双| 99re91这里只有精品| 欧美激情第6页| 你懂的网站在线| 天天综合天天做天天综合| 国产精品一区二区人妻喷水| 99精品国产福利在线观看免费| 国产日本一区二区三区| 国产高清自产拍av在线| 精品视频在线观看日韩| 精品成人无码久久久久久| 中文一区一区三区高中清不卡| 日本在线观看免费视频| 99re6这里只有精品| 99久热re在线精品996热视频| 不卡视频观看| 国产亚洲人成网站在线观看| 亚洲天堂狠狠干| 一区二区在线电影| 国产精品九九视频| 日韩主播视频在线| 咪咪色在线视频| 久久精品福利| 国产精品99久久久久久www| 免费a级人成a大片在线观看| 日韩免费电影网站| 日本中文字幕网| 中文字幕欧美国产| 亚洲911精品成人18网站| 激情文学一区| 日韩av高清在线播放| 国产精品美女久久久久人| 久久久久久久成人| 岛国在线大片| 日韩亚洲电影在线| 一区二区三区在线观看av| 国产精品婷婷午夜在线观看| 337p日本欧洲亚洲大胆张筱雨 | 欧美特级特黄aaaaaa在线看| 欧美性黄网官网| 三上悠亚在线观看视频| 成人福利在线看| 男操女免费网站| 亚洲人成人一区二区三区| 翔田千里亚洲一二三区| 深夜福利一区二区三区| 国产91色在线| 色呦呦久久久| 日韩一区二区精品视频| 亚洲欧洲精品视频| 91精品国产综合久久婷婷香蕉| 毛片视频网站在线观看| 亚洲色图视频免费播放| 这里只有久久精品| 国产成人av自拍| 韩国中文字幕av| 亚洲尤物影院| 日韩视频 中文字幕| 欧美中文字幕一区二区| 精品在线一区| 一区二区三区在线免费看 | 精品一区二区三区视频在线播放| 欧美一区二粉嫩精品国产一线天| a黄色片在线观看| 在线视频免费一区二区| 天堂中文在线观看视频| 日韩三级视频在线看| 正在播放木下凛凛xv99| 色综合久久99| 日韩精品一区二区av| 亚洲欧美日韩一区二区| 亚洲黄色网址大全| 久久综合资源网| 亚洲の无码国产の无码步美| 国产精品123| 日本高清一区二区视频| 免费人成在线不卡| 日本男人操女人| 母乳一区在线观看| 草草久久久无码国产专区| 欧美三级午夜理伦三级中文幕| 正在播放一区| 99精品网站| 一本色道久久99精品综合| 欧美色爱综合| 日韩一区二区电影在线观看| 九九视频精品全部免费播放| 免费在线观看91| 神马香蕉久久| 久久久久久久久久久久久9999| 99精品国产一区二区三区2021| 成人福利网站在线观看11| 欧美一区=区三区| 国产在线精品播放| 亚洲精品三区| 91亚洲国产成人精品性色| 只有精品亚洲| 99re在线视频上| japanese色系久久精品| 高清免费日韩| 免费看成人人体视频| 久久久影院一区二区三区| 欧美在线导航| 欧美一区二区高清在线观看| 国产在视频线精品视频www666| 欧洲精品国产| 日韩在线综合| 黄色污污在线观看| 激情国产一区| 国产极品美女高潮无套久久久 | 又大又长粗又爽又黄少妇视频| 国产精品538一区二区在线| 男生和女生一起差差差视频| 成人网男人的天堂| 久久国产精品无码一级毛片| 久久精品亚洲乱码伦伦中文| 国产精品av久久久久久无| 中文字幕一区二区三区四区 | 在线日本中文字幕| 久久精品一区中文字幕| 日本天码aⅴ片在线电影网站| 国产做受高潮69| 久久电影tv| 91精品视频专区| 成人性生交大片免费看中文视频| 六月婷婷久久| 欧美gay男男猛男无套| 99国产精品白浆在线观看免费| 国产精品尤物| 亚洲黄色av片| 97久久超碰国产精品电影| 国产视频不卡在线| 亚洲国产日日夜夜| 日韩av免费播放| 精品国产一区a| 黄色视屏网站在线免费观看| 久久影院资源网| 在线观看涩涩| 亚洲最大福利视频| 久久成人高清| 日本成人在线不卡| 久久精品网址| 四虎成人免费视频| 欧美国产精品v| 国产精品6666| 3d动漫精品啪啪| 黄色网址在线播放| 久久久久国产精品免费网站| 国产 日韩 欧美一区| 国产精华一区| 亚洲成人三区| 色一情一乱一伦一区二区三区日本| 国产精品1区2区3区在线观看| 人人妻人人澡人人爽| 亚洲国产人成综合网站| 97精品久久人人爽人人爽| 日韩黄色在线免费观看| mm1313亚洲国产精品美女| 国产精品久久久久久久久粉嫩av | 日本一区视频在线观看| 欧美天天视频| 亚洲高清av一区二区三区| 久久久夜色精品亚洲| 精品无码人妻一区二区三区品| 欧美日韩免费在线视频| 国产在线黄色| 5278欧美一区二区三区| youjizzjizz亚洲| avove在线观看| 日本成人中文字幕在线视频| aaaaaav| 五月婷婷久久丁香| 欧美一级淫片aaaaaa| 欧美国产亚洲视频| 91精品亚洲一区在线观看| 天天综合色天天综合色hd| 久久久水蜜桃av免费网站| av2014天堂网| 亚洲午夜av在线| 亚洲AV无码乱码国产精品牛牛 | 亚洲精品国产成人| 国产又色又爽又黄刺激在线视频| 91亚洲国产成人精品性色| 91成人网在线观看| 四虎成人在线播放| 亚洲视频一区在线| 国产特级黄色片| 欧美大片va欧美在线播放| 欧美欧美在线| 国产美女永久无遮挡| 国产999精品久久| 日本一区二区三区四区五区 | av资源种子在线观看| 国产成人自拍视频在线观看| 国产一区二区三区四区| 能在线观看的av网站| 中文字幕欧美日本乱码一线二线| 中文av免费观看| 久久精品中文字幕一区| 成人在线分类| 青草青青在线视频| 99久久久久久| 天堂免费在线视频| 在线观看精品国产视频| 亚洲美女色播| 欧美视频在线第一页| 成人sese在线| 久久国产黄色片| 一本色道久久综合亚洲精品小说| 久久久人成影片一区二区三区在哪下载 | 97超级碰碰碰久久久| 亚洲精品推荐| 污污动漫在线观看| 日韩理论片网站| 天天色综合av| 国产精品黄色av| 亚洲一区二区三区| av免费观看不卡| 色激情天天射综合网| 日本精品一区二区三区在线播放| 91免费电影网站| 99av国产精品欲麻豆| 四虎国产精品成人免费入口| 欧美精品成人一区二区三区四区| 羞羞的网站在线观看| 欧美久久久久久久| 麻豆精品国产传媒mv男同| 欧美另类视频在线观看| 精品亚洲国产成av人片传媒| 久久亚洲精品中文字幕| a天堂资源在线观看| 国产亚洲美州欧州综合国| 国产wwwxxx| 日本精品一区二区三区在线播放视频| 91欧美在线| 熟女人妻在线视频| 777欧美精品| 九色porny视频在线观看| 午夜欧美一区二区三区免费观看| 国产成人在线看| 黄色av一区二区| 久久久免费精品| 色88久久久久高潮综合影院| 国产女人18毛片水真多18 | 中文字幕色网站| 欧美日韩亚洲网| 在线看福利影| 日韩欧美在线一区二区| 成人av免费观看| 国产精品高潮呻吟久久久| 欧美一级bbbbb性bbbb喷潮片|