深挖JDK动态代理

最近在研究RPC框架,避免不了的就是在RPC调用中使用最多的则是动态代理的机制了,基于此,我们先来研究一下JDK动态代理

我们先来尝试着编写一下JDK动态代理的代码

  1. 由于JDK动态代理是基于接口的,所以不免需要先编写一个接口,并声明一个getHello方法
package cn.lonecloud.study.service;
 
import cn.lonecloud.study.dto.HelloDto;
 
public interface HelloService {
 
    HelloDto getHello(String name);
}
  1. 有了接口,肯定是需要实现类,并将getHello方法给予实现
package cn.lonecloud.study;
 
import cn.lonecloud.study.dto.HelloDto;
import cn.lonecloud.study.service.HelloService;

public class HelloImpl implements HelloService {
    @Override
    public HelloDto getHello(String name) {
        return new HelloDto();
    }
}  

这两个硬性条件有了,则我们来编写动态代理类了

  1. 首先我们先来了解两个API:

1. public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h):该类用于创建动态代理类的实例,

1. loader:类的类加载器:一般用户类为AppClassLoader,可通过类名.class.getClassLoader()获得

2. interfaces:接口数组,前面我们说过,jdk动态代理是基于接口来实现的,所以这个参数就是用来传递接口数组啦

3. h:用于具体实现Handler,也就是这里执行相关的主要业务逻辑的地方了

2. InvocationHandler:该接口用于实现动态代理类的相关业务逻辑

1. 通常需要使用动态代理的话必须实现该接口,并重写其里面的invoke方法。

2. invoke(Object proxy, Method method, Object[] args)throws Throwable;

1. proxy:代理类对象

2. method:执行的方法

3. args:相关的参数

编写相关的代理类

package cn.lonecloud.study;
 
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
 
public class ProxyDemo {
    //定义实现类对象
    Object target;
    //构造函数
    public ProxyDemo(Object target) {
        this.target = target;
    }
    //获取实现类方法
    @SuppressWarnings("unchecked")
    public <T> T getProxy(Class<T> clazz){
       //获取代理实例
        return(T) Proxy.newProxyInstance(clazz.getClassLoader(),new Class[]{clazz}, (proxy, method, args) -> {
            System.out.println(method.getName());
            //执行代理对象
            return method.invoke(target,args);
        });
    }
}

clazz.getClassLoader()获取的是类加载器,第二个参数创建了一个Class[]数组对象,由于传递过来的clazz为接口,所以可以这样写

执行:

HelloService proxy1 = new ProxyDemo(new HelloImpl()).getProxy(HelloService.class);
HelloDto demo = proxy1.getHello("demo");

我们来分析一下JDK生成动态的代理类究竟是个什么东西

  1. 将生成的代理类编程一个class文件,通过以下方法
public static void transClass() throws IOException {
    URL resource = rpcMain.class.getClass().getResource("/");
    byte[] bts = ProxyGenerator.generateProxyClass("$Proxy0", new Class[]{HelloService.class});
    File file = new File(resource.getPath(),"$Proxy0.class");
    if (!file.exists()){
        file.createNewFile();
    }
    FileOutputStream fos = new FileOutputStream(file);
    fos.write(bts);
    fos.flush();
    fos.close();
    System.out.println(resource.getPath());
}

主要是通过ProxyGenerator.generateProxyClass获取代理类,该方法第一个为生成该类的名字,可以通过DEBUG的形式获取,第二个参数为该动态代理类所实现的接口,然后获取其字节码文件,将该字节码文件写入到文件中

  1. 通过JD-GUI反编译代码
import cn.lonecloud.study.dto.HelloDto;
import cn.lonecloud.study.service.HelloService;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
//该类集成了Proxy代理类,和实现了HelloService接口
public final class $Proxy0 extends Proxy implements HelloService {
    //声明了一系列方法,为啥要声明这个呢?请看最后面的实现类
    private static Method m1;
    private static Method m3;
    private static Method m2;
    private static Method m0;
 
    public $Proxy0(InvocationHandler var1) throws  {
        super(var1);
    }
    //重写Object类中equals方法
    public final boolean equals(Object var1) throws  {
        try {
            //都通过代理形式调用
            return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }
    //实现getHello方法,通过代理形式
    public final HelloDto getHello(String var1) throws  {
        try {
            return (HelloDto)super.h.invoke(this, m3, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }
   //重写toString方法
    public final String toString() throws  {
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }
    //重写hashCode方法
    public final int hashCode() throws  {
        try {
            return (Integer)super.h.invoke(this, m0, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }
    //类初始化
    static {
        try {
            //加载Object类,并获取其equals方法
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
           //加载HelloService接口,并获取其getHello方法
            m3 = Class.forName("cn.lonecloud.study.service.HelloService").getMethod("getHello", Class.forName("java.lang.String"));
            //加载Object类,并获取其toString方法
            m2 = Class.forName("java.lang.Object").getMethod("toString");
             //加载Object类,并获取其hashCode方法         
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}
  1. 将字节码通过 javap -verbose $Proxy0来获取字节码
Classfile /Users/lonecloud/Documents/ideaCode/target/classes/$Proxy0.class
  Last modified 2018-6-9; size 2076 bytes
  MD5 checksum a9c607b2d44135c7672b37458cc16c23
public final class $Proxy0 extends java.lang.reflect.Proxy implements cn.lonecloud.study.service.HelloService
  minor version: 0
  major version: 49
  flags: ACC_PUBLIC, ACC_FINAL, ACC_SUPER
Constant pool:
    #1 = Utf8               <init>
    #2 = Utf8               (Ljava/lang/reflect/InvocationHandler;)V
    #3 = Utf8               Code
    #4 = Utf8               Exceptions
    #5 = Utf8               java/lang/reflect/Proxy
    #6 = Class              #5            // java/lang/reflect/Proxy
    #7 = NameAndType        #1:#2         // "<init>":(Ljava/lang/reflect/InvocationHandler;)V
    #8 = Methodref          #6.#7         // java/lang/reflect/Proxy."<init>":(Ljava/lang/reflect/InvocationHandler;)V
    #9 = Utf8               m1
   #10 = Utf8               Ljava/lang/reflect/Method;
   #11 = Utf8               equals
   #12 = Utf8               (Ljava/lang/Object;)Z
   #13 = Utf8               h
   #14 = Utf8               Ljava/lang/reflect/InvocationHandler;
   #15 = NameAndType        #13:#14       // h:Ljava/lang/reflect/InvocationHandler;
   #16 = Fieldref           #6.#15        // java/lang/reflect/Proxy.h:Ljava/lang/reflect/InvocationHandler;
   #17 = Utf8               $Proxy0
   #18 = Class              #17           // $Proxy0
   #19 = NameAndType        #9:#10        // m1:Ljava/lang/reflect/Method;
   #20 = Fieldref           #18.#19       // $Proxy0.m1:Ljava/lang/reflect/Method;
   #21 = Utf8               java/lang/Object
   #22 = Class              #21           // java/lang/Object
   #23 = Utf8               java/lang/reflect/InvocationHandler
   #24 = Class              #23           // java/lang/reflect/InvocationHandler
   #25 = Utf8               invoke
   #26 = Utf8               (Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
   #27 = NameAndType        #25:#26       // invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
   #28 = InterfaceMethodref #24.#27       // java/lang/reflect/InvocationHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
   #29 = Utf8               java/lang/Boolean
   #30 = Class              #29           // java/lang/Boolean
   #31 = Utf8               booleanValue
   #32 = Utf8               ()Z
   #33 = NameAndType        #31:#32       // booleanValue:()Z
   #34 = Methodref          #30.#33       // java/lang/Boolean.booleanValue:()Z
   #35 = Utf8               java/lang/Error
   #36 = Class              #35           // java/lang/Error
   #37 = Utf8               java/lang/RuntimeException
   #38 = Class              #37           // java/lang/RuntimeException
   #39 = Utf8               java/lang/Throwable
   #40 = Class              #39           // java/lang/Throwable
   #41 = Utf8               java/lang/reflect/UndeclaredThrowableException
   #42 = Class              #41           // java/lang/reflect/UndeclaredThrowableException
   #43 = Utf8               (Ljava/lang/Throwable;)V
   #44 = NameAndType        #1:#43        // "<init>":(Ljava/lang/Throwable;)V
   #45 = Methodref          #42.#44       // java/lang/reflect/UndeclaredThrowableException."<init>":(Ljava/lang/Throwable;)V
   #46 = Utf8               m3
   #47 = Utf8               getHello
   #48 = Utf8               (Ljava/lang/String;)Lcn/lonecloud/study/dto/HelloDto;
   #49 = NameAndType        #46:#10       // m3:Ljava/lang/reflect/Method;
   #50 = Fieldref           #18.#49       // $Proxy0.m3:Ljava/lang/reflect/Method;
   #51 = Utf8               cn/lonecloud/study/dto/HelloDto
   #52 = Class              #51           // cn/lonecloud/study/dto/HelloDto
   #53 = Utf8               m2
   #54 = Utf8               toString
   #55 = Utf8               ()Ljava/lang/String;
   #56 = NameAndType        #53:#10       // m2:Ljava/lang/reflect/Method;
   #57 = Fieldref           #18.#56       // $Proxy0.m2:Ljava/lang/reflect/Method;
   #58 = Utf8               java/lang/String
   #59 = Class              #58           // java/lang/String
   #60 = Utf8               m0
   #61 = Utf8               hashCode
   #62 = Utf8               ()I
   #63 = NameAndType        #60:#10       // m0:Ljava/lang/reflect/Method;
   #64 = Fieldref           #18.#63       // $Proxy0.m0:Ljava/lang/reflect/Method;
   #65 = Utf8               java/lang/Integer
   #66 = Class              #65           // java/lang/Integer
   #67 = Utf8               intValue
   #68 = NameAndType        #67:#62       // intValue:()I
   #69 = Methodref          #66.#68       // java/lang/Integer.intValue:()I
   #70 = Utf8               <clinit>
   #71 = Utf8               ()V
   #72 = Utf8               java.lang.Object
   #73 = String             #72           // java.lang.Object
   #74 = Utf8               java/lang/Class
   #75 = Class              #74           // java/lang/Class
   #76 = Utf8               forName
   #77 = Utf8               (Ljava/lang/String;)Ljava/lang/Class;
   #78 = NameAndType        #76:#77       // forName:(Ljava/lang/String;)Ljava/lang/Class;
   #79 = Methodref          #75.#78       // java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
   #80 = String             #11           // equals
   #81 = Utf8               getMethod
   #82 = Utf8               (Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
   #83 = NameAndType        #81:#82       // getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
   #84 = Methodref          #75.#83       // java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
   #85 = Utf8               cn.lonecloud.study.service.HelloService
   #86 = String             #85           // cn.lonecloud.study.service.HelloService
   #87 = String             #47           // getHello
   #88 = Utf8               java.lang.String
   #89 = String             #88           // java.lang.String
   #90 = String             #54           // toString
   #91 = String             #61           // hashCode
   #92 = Utf8               java/lang/NoSuchMethodException
   #93 = Class              #92           // java/lang/NoSuchMethodException
   #94 = Utf8               java/lang/NoSuchMethodError
   #95 = Class              #94           // java/lang/NoSuchMethodError
   #96 = Utf8               getMessage
   #97 = NameAndType        #96:#55       // getMessage:()Ljava/lang/String;
   #98 = Methodref          #40.#97       // java/lang/Throwable.getMessage:()Ljava/lang/String;
   #99 = Utf8               (Ljava/lang/String;)V
  #100 = NameAndType        #1:#99        // "<init>":(Ljava/lang/String;)V
  #101 = Methodref          #95.#100      // java/lang/NoSuchMethodError."<init>":(Ljava/lang/String;)V
  #102 = Utf8               java/lang/ClassNotFoundException
  #103 = Class              #102          // java/lang/ClassNotFoundException
  #104 = Utf8               java/lang/NoClassDefFoundError
  #105 = Class              #104          // java/lang/NoClassDefFoundError
  #106 = Methodref          #105.#100     // java/lang/NoClassDefFoundError."<init>":(Ljava/lang/String;)V
  #107 = Utf8               cn/lonecloud/study/service/HelloService
  #108 = Class              #107          // cn/lonecloud/study/service/HelloService
{
  public $Proxy0(java.lang.reflect.InvocationHandler) throws ;
    descriptor: (Ljava/lang/reflect/InvocationHandler;)V
    flags: ACC_PUBLIC
    Code:
      stack=10, locals=2, args_size=2
         0: aload_0
         1: aload_1
         2: invokespecial #8                  // Method java/lang/reflect/Proxy."<init>":(Ljava/lang/reflect/InvocationHandler;)V
         5: return
    Exceptions:
      throws

  public final boolean equals(java.lang.Object) throws ;
    descriptor: (Ljava/lang/Object;)Z
    flags: ACC_PUBLIC, ACC_FINAL
    Code:
      stack=10, locals=3, args_size=2
         0: aload_0
         1: getfield      #16                 // Field java/lang/reflect/Proxy.h:Ljava/lang/reflect/InvocationHandler;
         4: aload_0
         5: getstatic     #20                 // Field m1:Ljava/lang/reflect/Method;
         8: iconst_1
         9: anewarray     #22                 // class java/lang/Object
        12: dup
        13: iconst_0
        14: aload_1
        15: aastore
        16: invokeinterface #28,  4           // InterfaceMethod java/lang/reflect/InvocationHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
        21: checkcast     #30                 // class java/lang/Boolean
        24: invokevirtual #34                 // Method java/lang/Boolean.booleanValue:()Z
        27: ireturn
        28: athrow
        29: astore_2
        30: new           #42                 // class java/lang/reflect/UndeclaredThrowableException
        33: dup
        34: aload_2
        35: invokespecial #45                 // Method java/lang/reflect/UndeclaredThrowableException."<init>":(Ljava/lang/Throwable;)V
        38: athrow
      Exception table:
         from    to  target type
             0    28    28   Class java/lang/Error
             0    28    28   Class java/lang/RuntimeException
             0    28    29   Class java/lang/Throwable
    Exceptions:
      throws

  public final cn.lonecloud.study.dto.HelloDto getHello(java.lang.String) throws ;
    descriptor: (Ljava/lang/String;)Lcn/lonecloud/study/dto/HelloDto;
    flags: ACC_PUBLIC, ACC_FINAL
    Code:
      stack=10, locals=3, args_size=2
         0: aload_0
         1: getfield      #16                 // Field java/lang/reflect/Proxy.h:Ljava/lang/reflect/InvocationHandler;
         4: aload_0
         5: getstatic     #50                 // Field m3:Ljava/lang/reflect/Method;
         8: iconst_1
         9: anewarray     #22                 // class java/lang/Object
        12: dup
        13: iconst_0
        14: aload_1
        15: aastore
        16: invokeinterface #28,  4           // InterfaceMethod java/lang/reflect/InvocationHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
        21: checkcast     #52                 // class cn/lonecloud/study/dto/HelloDto
        24: areturn
        25: athrow
        26: astore_2
        27: new           #42                 // class java/lang/reflect/UndeclaredThrowableException
        30: dup
        31: aload_2
        32: invokespecial #45                 // Method java/lang/reflect/UndeclaredThrowableException."<init>":(Ljava/lang/Throwable;)V
        35: athrow
      Exception table:
         from    to  target type
             0    25    25   Class java/lang/Error
             0    25    25   Class java/lang/RuntimeException
             0    25    26   Class java/lang/Throwable
    Exceptions:
      throws

  public final java.lang.String toString() throws ;
    descriptor: ()Ljava/lang/String;
    flags: ACC_PUBLIC, ACC_FINAL
    Code:
      stack=10, locals=2, args_size=1
         0: aload_0
         1: getfield      #16                 // Field java/lang/reflect/Proxy.h:Ljava/lang/reflect/InvocationHandler;
         4: aload_0
         5: getstatic     #57                 // Field m2:Ljava/lang/reflect/Method;
         8: aconst_null
         9: invokeinterface #28,  4           // InterfaceMethod java/lang/reflect/InvocationHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
        14: checkcast     #59                 // class java/lang/String
        17: areturn
        18: athrow
        19: astore_1
        20: new           #42                 // class java/lang/reflect/UndeclaredThrowableException
        23: dup
        24: aload_1
        25: invokespecial #45                 // Method java/lang/reflect/UndeclaredThrowableException."<init>":(Ljava/lang/Throwable;)V
        28: athrow
      Exception table:
         from    to  target type
             0    18    18   Class java/lang/Error
             0    18    18   Class java/lang/RuntimeException
             0    18    19   Class java/lang/Throwable
    Exceptions:
      throws

  public final int hashCode() throws ;
    descriptor: ()I
    flags: ACC_PUBLIC, ACC_FINAL
    Code:
      stack=10, locals=2, args_size=1
         0: aload_0
         1: getfield      #16                 // Field java/lang/reflect/Proxy.h:Ljava/lang/reflect/InvocationHandler;
         4: aload_0
         5: getstatic     #64                 // Field m0:Ljava/lang/reflect/Method;
         8: aconst_null
         9: invokeinterface #28,  4           // InterfaceMethod java/lang/reflect/InvocationHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
        14: checkcast     #66                 // class java/lang/Integer
        17: invokevirtual #69                 // Method java/lang/Integer.intValue:()I
        20: ireturn
        21: athrow
        22: astore_1
        23: new           #42                 // class java/lang/reflect/UndeclaredThrowableException
        26: dup
        27: aload_1
        28: invokespecial #45                 // Method java/lang/reflect/UndeclaredThrowableException."<init>":(Ljava/lang/Throwable;)V
        31: athrow
      Exception table:
         from    to  target type
             0    21    21   Class java/lang/Error
             0    21    21   Class java/lang/RuntimeException
             0    21    22   Class java/lang/Throwable
    Exceptions:
      throws

  static {} throws ;
    descriptor: ()V
    flags: ACC_STATIC
    Code:
      stack=10, locals=2, args_size=0
         0: ldc           #73                 // String java.lang.Object
         2: invokestatic  #79                 // Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
         5: ldc           #80                 // String equals
         7: iconst_1
         8: anewarray     #75                 // class java/lang/Class
        11: dup
        12: iconst_0
        13: ldc           #73                 // String java.lang.Object
        15: invokestatic  #79                 // Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
        18: aastore
        19: invokevirtual #84                 // Method java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
        22: putstatic     #20                 // Field m1:Ljava/lang/reflect/Method;
        25: ldc           #86                 // String cn.lonecloud.study.service.HelloService
        27: invokestatic  #79                 // Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
        30: ldc           #87                 // String getHello
        32: iconst_1
        33: anewarray     #75                 // class java/lang/Class
        36: dup
        37: iconst_0
        38: ldc           #89                 // String java.lang.String
        40: invokestatic  #79                 // Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
        43: aastore
        44: invokevirtual #84                 // Method java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
        47: putstatic     #50                 // Field m3:Ljava/lang/reflect/Method;
        50: ldc           #73                 // String java.lang.Object
        52: invokestatic  #79                 // Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
        55: ldc           #90                 // String toString
        57: iconst_0
        58: anewarray     #75                 // class java/lang/Class
        61: invokevirtual #84                 // Method java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
        64: putstatic     #57                 // Field m2:Ljava/lang/reflect/Method;
        67: ldc           #73                 // String java.lang.Object
        69: invokestatic  #79                 // Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
        72: ldc           #91                 // String hashCode
        74: iconst_0
        75: anewarray     #75                 // class java/lang/Class
        78: invokevirtual #84                 // Method java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
        81: putstatic     #64                 // Field m0:Ljava/lang/reflect/Method;
        84: return
        85: astore_1
        86: new           #95                 // class java/lang/NoSuchMethodError
        89: dup
        90: aload_1
        91: invokevirtual #98                 // Method java/lang/Throwable.getMessage:()Ljava/lang/String;
        94: invokespecial #101                // Method java/lang/NoSuchMethodError."<init>":(Ljava/lang/String;)V
        97: athrow
        98: astore_1
        99: new           #105                // class java/lang/NoClassDefFoundError
       102: dup
       103: aload_1
       104: invokevirtual #98                 // Method java/lang/Throwable.getMessage:()Ljava/lang/String;
       107: invokespecial #106                // Method java/lang/NoClassDefFoundError."<init>":(Ljava/lang/String;)V
       110: athrow
      Exception table:
         from    to  target type
             0    85    85   Class java/lang/NoSuchMethodException
             0    85    98   Class java/lang/ClassNotFoundException
    Exceptions:
      throws

总结: 代理对象生成类:

  1. 该代理对象会将该接口的的方法进行一次封装通过调用super.h.invoke(this, m0, (Object[])null);将执行之前定义的InvolicationHandler类中的invoke方法然后再调用我们之前编写的类方法。

  2. 会将Object类中的toString,equals,hashCode这些方法进行代理

  3. 将InvocationHandler通过成员变量的形式传递到类中

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,826评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,968评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,234评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,562评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,611评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,482评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,271评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,166评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,608评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,814评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,926评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,644评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,249评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,866评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,991评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,063评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,871评论 2 354

推荐阅读更多精彩内容

  • title: Jdk动态代理原理解析 tags:代理 categories:笔记 date: 2017-06-14...
    行径行阅读 19,263评论 3 36
  • 本篇文章是把我认为吴军的《谷歌方法论中的回信精选知识之外的个人素养》有用的知识点融入到我的认知体系(即我自己对柯维...
    Hammer王阅读 470评论 0 0
  • 他大概是我所见过的长得最像米其林的人了,第二像的是他女儿。圆脸,圆鼓鼓的肚子,椭圆形的四肢,一米八几的个子,走起路...
    哇啦哇啦119阅读 199评论 0 0
  • 表白不被拒绝一下 你还真以为自己是个小仙女呐 你不够喜欢我 我也不会喜欢你 我做不到那种不求回报的喜欢一个人 不分...
    瞻瞻痴阅读 145评论 0 0
  • 开篇,我想从死亡开始。 每个人从出生,便开始死亡倒计时,并且谁都无法预知生命戛然而止的那个时刻。我看到过有的人在接...
    PeterHou阅读 175评论 0 0