在文章JAVA设计模式-动态代理(Proxy)示例及说明JAVA设计模式-动态代理(Proxy)源码分析都提到了反射这个概念。

 // 通过反射机制,通知力宏做事情
method.invoke(object, args);
// 通过反射,将h作为参数,实例化代理类,返回代理类实例。
return cons.newInstance(new Object[]{h});

而且在

// 将接口类对象数组clone一份。
final Class<?>[] intfs = interfaces.clone();

也提到一个类对象数组的概念,如果你不知道反射,不知道类对象,那么你在阅读者两篇文章的时候,很可能就会雨里雾里,不知所然。通过这篇文章你就能很轻松的掌握类对象和反射。

反射是java语言中一个很基础,很简单的知识,不仅仅是在工作中会用到,而且也会经常出现在面试中。如果你认真阅读本文,对你在技术层面来说又是一个提升。

一,前言

  反射是什么呢?其实是java程序语言的一种机制,我理解为是java的后门。在其他文章中给出的定义和解释都比较晦涩难懂,不如先看一下具体的代码,再去理解,这样就容易很多。

  为了更好的理解反射机制,不得不提到类对象的概念,为了不与类和对象的概念搞混,我们就首先看一下类和对象的概念。相信你已经非常熟悉类和对象的概念了,那么我就简单的描述一下类与对象的概念:

    类:一个或一组事物的抽象描述,例如狗是对狗狗这一组事物的抽象描述。

    对象:具体的某一个事物,例如哈士奇等,也可以说是类的一个实例。

  那么类对象是什么呢?

    在java中一切皆对象。既然一切皆对象,当然类也是一种对象,那么类的对象类型是什么呢?是java.lang.Class,你也许在其他的地方见到过。

  那么类对象是从哪里来的,怎么创建的呢?

    我们都知道,想要得到一个类的对象,最基本的方法就是通过new关键字,去实例化一个对象。但类对象是一个特殊的对象,自然不能使用new关键字,翻看Class类的源码就可以证明:

    /*
* 私有化构造方法,只有java 虚拟机才能创建类对象
* Private constructor. Only the Java Virtual Machine creates Class objects.
* This constructor is not used and prevents the default constructor being
* generated.
*/
private Class(ClassLoader loader) {
// Initialize final field for classLoader. The initialization value of non-null
// prevents future JIT optimizations from assuming this final field is null.
classLoader = loader;
}

  Class类中只有这一个私有的构造方法。其实类对象是java虚拟机(JVM)在加载class文件的时候自动在虚拟机内存中给我们创建的。

    这里就涉及到了另外一个机制:类加载机制。

    简单描述一下类加载机制:就是虚拟机将class文件加载到虚拟机内存中,最终形成可以被虚拟机直接使用的java类型。虚拟机会将class文件中的信息按照所需的存储格式放在方法区中,同时会在内存中(HotSpot是在堆内存中)实例化一个java.lang.Class类对象。

  类加载机制是一个很复杂的过程,不是本篇文章的重点,就不展开来说。至少到这里我们已经知道了,类对象是由虚拟机创建的而且HotSpot虚拟机将类对象存放在堆内存中。

  那么怎么通过类对象来实现反射呢?为了理解方便,来举一个有趣的例子

二,一个有趣的例子

  有一天一个同事养了一只狗狗哈士奇,在作者面前大肆炫耀,说他的狗狗多么萌,多么威武,多么听话......,作者听完心生向往,提出去看一看。但是这个同事高傲的抬起头说了三个字:想的美。

  竟然不给我看!!!作者一气之下,就走了java程序的后门-反射。你不让我看,我偏偏要看。

  哈士奇类的定义:

package com.zcz.reflecttest;

public class HaShiQi implements Dog {
public String color = "黑色";
private String name = "富贵"; //私有化构造
private HaShiQi() {};
@Override
public void eat() {
// TODO Auto-generated method stub
System.out.println(name + " 去吃狗粮");
} @Override
public void run() {
// TODO Auto-generated method stub
System.out.println(name + " 去跑着玩儿");
} private void dance() {
System.out.println(name + " 来跳一支舞");
} @Override
public String toString() {
// TODO Auto-generated method stub
return "名字:"+name+";颜色:"+color;
}
}

  可以看到同时的哈士奇实现了Dog接口:

package com.zcz.reflecttest;

public interface Dog {
public void eat();
public void run();
}

  从代码中可以看到,我的同事不仅仅没告诉作者他的哈士奇竟然会跳舞,甚至连哈士奇的名字都不想让作者知道,而且连构造器都私有化了。

  那么接下来,走后门开始。在上提到类对象,正好我想通过反射看狗狗,也需要用到类对象。那么接下来第一步就先获取HaShiQi的类对象。

三,类对象的获取

  超级简单:

package com.zcz.reflecttest;

/**
* 通过反射查看同事狗狗的信息
* @author zhangchengzi
*
*/
public class LookLook { public static void main(String[] args) {
// TODO Auto-generated method stub
//获取类对象,除了这份方法外还有另外两种方法
Class clazz = HaShiQi.class; } }

  从这里开始我们的反射的使用的开始了,先看看HaShiQi类中有哪些属性吧?

四,获取属性

  代码:

public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
// TODO Auto-generated method stub
//获取类对象,除了这份方法外还有另外两种方法
Class clazz = HaShiQi.class; System.out.println("——————— 获取所有公有的属性 —————————");
Field[] fields = clazz.getFields();
for(Field field : fields) {
field.setAccessible(true);
System.out.println(field);
}
}

  打印结果:

——————— 获取所有公有的属性  —————————
public java.lang.String com.zcz.reflecttest.HaShiQi.color

  可以看到只有一个color属性,使用getFields方法是获取不到私有属性了,想要获取私有属性就要使用下方的方法:

public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
// TODO Auto-generated method stub
//获取类对象,除了这份方法外还有另外两种方法
Class clazz = HaShiQi.class; System.out.println("——————— 获取所有公有的属性 —————————");
Field[] fields = clazz.getFields();
for(Field field : fields) {
field.setAccessible(true);
System.out.println(field);
} System.out.println("——————— 获取所有的属性 —————————");
fields = clazz.getDeclaredFields();
for(Field field : fields) {
field.setAccessible(true);
System.out.println(field);
}
}

  打印结果:

——————— 获取所有公有的属性  —————————
public java.lang.String com.zcz.reflecttest.HaShiQi.color
——————— 获取所有的属性 —————————
public java.lang.String com.zcz.reflecttest.HaShiQi.color
private java.lang.String com.zcz.reflecttest.HaShiQi.name

  可以看到,HaShiQi类中私有(private修饰的)的name属性打印出来了。

五,获取方法

  代码:

public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
// TODO Auto-generated method stub
//获取类对象,除了这份方法外还有另外两种方法
Class clazz = HaShiQi.class; System.out.println("——————— 获取所有公有的属性 —————————");
Field[] fields = clazz.getFields();
for(Field field : fields) {
field.setAccessible(true);
System.out.println(field);
} System.out.println("——————— 获取所有的属性 —————————");
fields = clazz.getDeclaredFields();
for(Field field : fields) {
field.setAccessible(true);
System.out.println(field);
}
System.out.println("——————— 获取所有公有的方法 —————————");
Method[] methods = clazz.getMethods();
for(Method method : methods) {
System.out.println(method);
}
}

  打印结果:

——————— 获取所有公有的属性  —————————
public java.lang.String com.zcz.reflecttest.HaShiQi.color
——————— 获取所有的属性 —————————
public java.lang.String com.zcz.reflecttest.HaShiQi.color
private java.lang.String com.zcz.reflecttest.HaShiQi.name
——————— 获取所有公有的方法 —————————
public void com.zcz.reflecttest.HaShiQi.run()
//重写的toString 方法
public java.lang.String com.zcz.reflecttest.HaShiQi.toString()
public void com.zcz.reflecttest.HaShiQi.eat()
//Object类中的方法
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()

  从结果中可以发现,getMethod方法也是只能获取到公有的方法,而且连Object中的方法也获取到了。跟获取属性也是一样的,也有方法可以获取到HaShiQi类中所有的方法:

public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
// TODO Auto-generated method stub
//获取类对象,除了这份方法外还有另外两种方法
Class clazz = HaShiQi.class; System.out.println("——————— 获取所有公有的属性 —————————");
Field[] fields = clazz.getFields();
for(Field field : fields) {
field.setAccessible(true);
System.out.println(field);
} System.out.println("——————— 获取所有的属性 —————————");
fields = clazz.getDeclaredFields();
for(Field field : fields) {
field.setAccessible(true);
System.out.println(field);
}
System.out.println("——————— 获取所有公有的方法 —————————");
Method[] methods = clazz.getMethods();
for(Method method : methods) {
System.out.println(method);
}
System.out.println("——————— 获取所有类中声明的方法 —————————");
methods = clazz.getDeclaredMethods();
for(Method method : methods) {
System.out.println(method);
}
}

  打印结果:

——————— 获取所有公有的属性  —————————
public java.lang.String com.zcz.reflecttest.HaShiQi.color
——————— 获取所有的属性 —————————
public java.lang.String com.zcz.reflecttest.HaShiQi.color
private java.lang.String com.zcz.reflecttest.HaShiQi.name
——————— 获取所有公有的方法 —————————
public void com.zcz.reflecttest.HaShiQi.run()
public java.lang.String com.zcz.reflecttest.HaShiQi.toString()
public void com.zcz.reflecttest.HaShiQi.eat()
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
——————— 获取所有类中声明的方法 —————————
public void com.zcz.reflecttest.HaShiQi.run()
public java.lang.String com.zcz.reflecttest.HaShiQi.toString()
private void com.zcz.reflecttest.HaShiQi.dance()
public void com.zcz.reflecttest.HaShiQi.eat()

  这样就可以同时获取到HaShiQi类中的私有方法(private修饰的)dance了。

六,获取构造器

  代码:

public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
// TODO Auto-generated method stub
//获取类对象,除了这份方法外还有另外两种方法
Class clazz = HaShiQi.class; System.out.println("——————— 获取所有公有的属性 —————————");
Field[] fields = clazz.getFields();
for(Field field : fields) {
field.setAccessible(true);
System.out.println(field);
} System.out.println("——————— 获取所有的属性 —————————");
fields = clazz.getDeclaredFields();
for(Field field : fields) {
field.setAccessible(true);
System.out.println(field);
}
System.out.println("——————— 获取所有公有的方法 —————————");
Method[] methods = clazz.getMethods();
for(Method method : methods) {
System.out.println(method);
}
System.out.println("——————— 获取所有类中声明的方法 —————————");
methods = clazz.getDeclaredMethods();
for(Method method : methods) {
System.out.println(method);
}
System.out.println("——————— 获取所有公有的构造器 —————————");
Constructor[] constructors = clazz.getConstructors();
for(Constructor constructor : constructors) {
System.out.println(constructor);
} }

  打印结果:

——————— 获取所有公有的属性  —————————
public java.lang.String com.zcz.reflecttest.HaShiQi.color
——————— 获取所有的属性 —————————
public java.lang.String com.zcz.reflecttest.HaShiQi.color
private java.lang.String com.zcz.reflecttest.HaShiQi.name
——————— 获取所有公有的方法 —————————
public void com.zcz.reflecttest.HaShiQi.run()
public java.lang.String com.zcz.reflecttest.HaShiQi.toString()
public void com.zcz.reflecttest.HaShiQi.eat()
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
——————— 获取所有类中声明的方法 —————————
public void com.zcz.reflecttest.HaShiQi.run()
public java.lang.String com.zcz.reflecttest.HaShiQi.toString()
private void com.zcz.reflecttest.HaShiQi.dance()
public void com.zcz.reflecttest.HaShiQi.eat()
——————— 获取所有公有的构造器 —————————

  因为HaShiQi类中没有公有的构造器,所以这里什么都没有打印出来。自然也有获取到私有构造器的方法:

public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
// TODO Auto-generated method stub
//获取类对象,除了这份方法外还有另外两种方法
Class clazz = HaShiQi.class; System.out.println("——————— 获取所有公有的属性 —————————");
Field[] fields = clazz.getFields();
for(Field field : fields) {
field.setAccessible(true);
System.out.println(field);
} System.out.println("——————— 获取所有的属性 —————————");
fields = clazz.getDeclaredFields();
for(Field field : fields) {
field.setAccessible(true);
System.out.println(field);
}
System.out.println("——————— 获取所有公有的方法 —————————");
Method[] methods = clazz.getMethods();
for(Method method : methods) {
System.out.println(method);
}
System.out.println("——————— 获取所有类中声明的方法 —————————");
methods = clazz.getDeclaredMethods();
for(Method method : methods) {
System.out.println(method);
}
System.out.println("——————— 获取所有公有的构造器 —————————");
Constructor[] constructors = clazz.getConstructors();
for(Constructor constructor : constructors) {
System.out.println(constructor);
}
System.out.println("——————— 获取所有的构造器 —————————");
constructors = clazz.getDeclaredConstructors();
for(Constructor constructor : constructors) {
System.out.println(constructor);
}
}

  打印结果:

——————— 获取所有公有的属性  —————————
public java.lang.String com.zcz.reflecttest.HaShiQi.color
——————— 获取所有的属性 —————————
public java.lang.String com.zcz.reflecttest.HaShiQi.color
private java.lang.String com.zcz.reflecttest.HaShiQi.name
——————— 获取所有公有的方法 —————————
public void com.zcz.reflecttest.HaShiQi.run()
public java.lang.String com.zcz.reflecttest.HaShiQi.toString()
public void com.zcz.reflecttest.HaShiQi.eat()
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
——————— 获取所有类中声明的方法 —————————
public void com.zcz.reflecttest.HaShiQi.run()
public java.lang.String com.zcz.reflecttest.HaShiQi.toString()
private void com.zcz.reflecttest.HaShiQi.dance()
public void com.zcz.reflecttest.HaShiQi.eat()
——————— 获取所有公有的构造器 —————————
——————— 获取所有的构造器 —————————
private com.zcz.reflecttest.HaShiQi()

七,实例化对象

  HaSHiQi类中的信息,包括属性,方法,构造器,我们都已经通过反射浏览了一遍,那么接下来就要再使用反射实例化HaShiQi类的对象了,因为只有实例对象才能调用属性和方法。

  因为HaShiQi类中只显示声明了一个空参构造器,所以我们只能使用这个构造器来实例化对象。

  正常情况下获取指定参数的构造器,需要使用方法clazz.getConstructor(parameterTypes(参数类对象数组))。但是HaShiQi的构造方法是私有的,所以使用这个方法去获取构造器会报错:

Constructor cons = clazz.getConstructor();
Exception in thread "main" java.lang.NoSuchMethodException: com.zcz.reflecttest.HaShiQi.<init>()
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.getConstructor(Class.java:1825)
at com.zcz.reflecttest.LookLook.main(LookLook.java:61)

  所以我们使用另外一个方法解决这个问题:

        // 实例化对象
// 获取构造器
Constructor con = clazz.getDeclaredConstructor();
// 强制设置为可以访问
con.setAccessible(true);
HaShiQi haShiQi = (HaShiQi)con.newInstance();
System.out.println("没有做任何修改前:"+haShiQi.toString());

  打印结果:  

没有做任何修改前:名字:富贵;颜色:黑色

  哈哈,机智如我,怎么能被这种问题打到,从代码中可以看到我们使用了构造器的newInstance方法实例化了一个HaShiQi对象。

    代码:con.newInstance();

    是不是很熟悉?,在文章JAVA设计模式-动态代理(Proxy)源码分析中,实例化代理类对象的时候,也使用到了:

// 通过反射,将h作为参数,实例化代理类,返回代理类实例。
return cons.newInstance(new Object[]{h});

  接下来就是访问对象的属性和方法了如果我们把所有的属性和方法都访问到,不就把同事的狗狗看了一遍了吗?。

八,修改属性

        // 修改狗狗的颜色
// 获取狗狗的color属性
Field filed = clazz.getField("color");
filed.set(haShiQi, "红色");
System.out.println("修改狗狗的颜色:"+haShiQi.toString());

  打印结果: 

没有做任何修改前:名字:富贵;颜色:黑色
修改狗狗的颜色:名字:富贵;颜色:红色

  修改成功,接着修改狗狗的名字:

// 修改狗狗的颜色
// 获取狗狗的color属性
Field filed = clazz.getField("color");
filed.set(haShiQi, "红色");
System.out.println("修改狗狗的颜色:"+haShiQi.toString());
// 修改狗狗的名字
filed = clazz.getDeclaredField("name");
// 强制设置为可以访问
filed.setAccessible(true);
filed.set(haShiQi, "惊喜");
System.out.println("修改狗狗的名字:"+haShiQi.toString());

  打印结果:

没有做任何修改前:名字:富贵;颜色:黑色
修改狗狗的颜色:名字:富贵;颜色:红色
修改狗狗的名字:名字:惊喜;颜色:红色

  修改成功,但是千万要注意是的是的getDeclaredField方法,而不是getField方法,使用getField方法会抛出异常:Exception in thread "main" java.lang.NoSuchFieldException: name;

  同时filed.setAccessible(true);也是必不可少了,否则将抛出异常:Exception in thread "main" java.lang.IllegalAccessException: Class com.zcz.reflecttest.LookLook can not access a member of class com.zcz.reflecttest.HaShiQi with modifiers "private"

  属性修改完,我们就开始调用方法吧。

九,调用方法

        //调用run方法
Method method = clazz.getMethod("run");
method.invoke(haShiQi, null);

  打印结果:

惊喜 去跑着玩儿

  调用成功;

    代码:method.invoke(haShiQi, null);

  是不是觉得这句代码也是很熟悉的?在文章JAVA设计模式-动态代理(Proxy)示例及说明中也有相同的用法:

 // 通过反射机制,通知力宏做事情
method.invoke(object, args);

  我们继续,eat方法和run方法一样,都是公有的方法,这里就不再演示了,接下来演示一下私有的dance方法:

        //调用run方法
Method method = clazz.getMethod("run");
method.invoke(haShiQi, null);
//调用dance方法
method = clazz.getDeclaredMethod("dance");
method.setAccessible(true);
method.invoke(haShiQi, null);

  打印结果:

惊喜 去跑着玩儿
惊喜 来跳一支舞

  也同样成功了,但是也要注意getDeclaredMethod方法和method.setAccessible(true);

  到这里,同事不让我看的狗狗,我通过java的反射机制从里到外的全部都看了一遍,不仅仅是看了一遍,我还给他的狗狗改了颜色和名字。调用了所有的方法。是不是很神奇,很有成就感?

十,总结

  反射的基本用法已经都在上面的实例中演示到了,但是反射还是有其他的方法在这里并没有提到,有机会的话继续补充。

  在上面的代码过程中,你也许也发现了,不仅仅是有类对象,而且还有属性,方法和构造器都是对象,属性是java.lang.reflect.Field类的对象,方法是java.lang.reflect.Method类的对象,构造器是java.lang.reflect.Constructor类的对象。看来在java中确实是一切皆对象。

  

  好了,来看看其他文章中对反射的解释吧:

  Java 反射机制是在运行状态中,对于任意一个类,都能够获得这个类的所有属性和方法,对于任意一个对象都能够调用它的任意一个属性和方法。这种在运行时动态的获取信息以及动态调用对象的方法的功能称为 Java 的反射机制。

  在上面的例子中,我们是不是在运行中,获取了HaShiQi的属性和方法(包括私有的),是不是调用了每一个属性和方法(包括私有的)。

  这样一来,反射机制是不是好理解一点儿了呢,希望能帮到你。


原创不易,转载请注明出处:https://www.cnblogs.com/zhangchengzi/p/9723250.html

Java程序语言的后门-反射机制的更多相关文章

  1. 深入理解java:1.1.1. 反射机制

    反射 到底什么是反射(Reflection)呢? 反射有时候也被称为内省(Introspection),事实上,反射,就是一种内省的方式, Java不允许在运行时改变程序结构或类型变量的结构,但它允许 ...

  2. java温故而知新(8)反射机制

    一.什么是反射机制  简单的来说,反射机制指的是程序在运行时能够获取自身的信息.在java中,只要给定类的名字, 那么就可以通过反射机制来获得类的所有信息. 二.哪里用到反射机制  有些时候,我们用过 ...

  3. Java 从入门到精通-反射机制

    导读 Java反射机制是开发者迈向结构化开发的重要一步,同时掌握了反射机制也就掌握了所有框架的核心实现思想. 认识反射机制 简单例子 通过以上的程序就会发现,除了对象的正向处理操作之外,还可以通过ge ...

  4. Java基础系列 - 泛型和反射机制

    package com.test5; import java.lang.reflect.Field; import java.lang.reflect.Method; /** * Java泛型和反射机 ...

  5. Java程序执行过程及内存机制

    本讲将介绍Java代码是如何一步步运行起来的,其中涉及的编译器,类加载器,字节码校验器,解释器和JIT编译器在整个过程中是发挥着怎样的作用.此外还会介绍Java程序所占用的内存是被如何管理的:堆.栈和 ...

  6. 编写Java程序,使用Swing事件处理机制实现用户登录和英雄信息显示

    返回本章节 返回作业目录 需求说明: 使用Swing事件处理机制实现用户登录和英雄信息显示 实现思路: 创建LoginView类,该类用于显示登录界面,为登录按钮添加ActionListener事件, ...

  7. 【Java】代理模式、反射机制-动态代理

    关于代理模式和动态代理参考自:https://www.cnblogs.com/gonjan-blog/p/6685611.html 这里通过参考博客中的例子整理个人理解. 代理模式: 访问某个类的方法 ...

  8. 谷歌希望让 Swift 成为安卓的优先选择,以取代由 Oracle 开发的 Java 程序语言。

    http://news.coolban.com/Web/Index/land/app/2/id/405239

  9. Java反射机制及IoC原理

    一. 反射机制概念 主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义.在java中,只要给定类的名字, 那么就可以通 ...

随机推荐

  1. Shrio使用Jwt达到前后端分离

    概述 前后端分离之后,因为HTTP本身是无状态的,Session就没法用了.项目采用jwt的方案后,请求的主要流程如下:用户登录成功之后,服务端会创建一个jwt的token(jwt的这个token中记 ...

  2. Kafka到底有几个Offset?——Kafka核心之偏移量机制

    ​ Kafka是由LinkIn开源的实时数据处理框架,目前已经更新到2.3版本.不同于一般的消息中间件,Kafka通过数据持久化和磁盘读写获得了极高的吞吐量,并可以不依赖Storm,SparkStre ...

  3. Python之基本数据类型概览

    Python之基本数据类型概览 什么是数据类型? 每一门编程语言都有自己的数据类型,例如最常见的数字1,2,3.....,字符串'小明','age','&D8'...,这些都是数据类型中的某一 ...

  4. UnityScript基础

    基本格式 1 cc.Class({ 2 extends: cc.Component, 3 4 properties: { 5 }, 6 7 // use this for initialization ...

  5. unity编辑器扩展_08(创建自定义窗口)

    代码: using UnityEngine;using UnityEditor; public class MyWidow : EditorWindow{    [MenuItem("Win ...

  6. 使用wait/notify/notifyAll实现线程间通信的几点重要说明

    在Java中,可以通过配合调用Object对象的wait()方法和notify()方法或notifyAll()方法来实现线程间的通信.在线程中调用wait()方法,将阻塞等待其他线程的通知(其他线程调 ...

  7. Jconsole/jvisualvm远程监控weblogic中间件配置

    1.进入linu操作界面,进入到启动服务目录下 2.选择要监控的服务的启动项,进入到编辑状态(注意:要先将该文件进行备份),如下图所示 3.修改USER_AGRS域,添加如下内容,注意修改IP USE ...

  8. Super和This总结

    this: this是自身的一个对象,代表对象本身,可以理解为:指向对象本身的一个指针. Java关键字this只能用于方法体内.当一个对象创建后,Java虚拟机(JVM)就会给这个对象分配一个引用自 ...

  9. NLP(二十二)使用LSTM进行语言建模以预测最优词

    预处理 数据集使用Facebook上的BABI数据集 将文件提取成可训练的数据集,包括:文章 问题 答案 def get_data(infile): stories,questions,answers ...

  10. CF - 1117 F Crisp String

    题目传送门 题解: 枚举非法对. 如果 ‘a'  和 ’b' 不能相邻的话,那么删除 'a' 'b'之间的字符就是非法操作了. 假设题目给定的字符串为 "acdbe",所以删除cd ...