• 单例模式-反射攻击的解决方案及原理分析


    首先我们还是拿饿汉模式作为栗子进行测试,饿汉模式的代码如下:

    public class HungrySingleton implements Serializable {
    
        private static final HungrySingleton instance;
    
        static {
            instance = new HungrySingleton();
        }
        private HungrySingleton(){
        }
    
        public static HungrySingleton getInstance(){
            return instance;
        }
    
        private Object readResolve(){
            return instance;
        }
    

      1、先写一个利用反射获取实例的方法和直接获取实例的方法,将两者的返回值进行比较,看返回的是否是一个实例。

    代码如下:

    public class Testreflection {
        public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
            Class object = HungrySingleton.class;
            Constructor constructor = object.getDeclaredConstructor();
            constructor.setAccessible(true);
    
            HungrySingleton instance = HungrySingleton.getInstance();
            HungrySingleton newInstance = (HungrySingleton) constructor.newInstance();
    
            System.out.println(instance);
            System.out.println(newInstance);
            System.out.println(instance == newInstance);
    
         }
        }
    

      运行后的结果为:可见,两者的结果并不是一个对象,则饿汉模式毅然受到了反射的攻击。

    2、那么改如何解决这反射攻击呢?我们知道是在类加载的时候就加载了这个实例的,因为是在类加载的时候就生成了词实例,那么我们可以在构造器里面加一个判断,进行反射防御。代码如下:

    测试结果为:

    这种方式有一个特点,也就是它对类加载这个时刻就把对象创建好的这种类是ok的,静态内部类的单例也可以用。
    对于不是静态类的也需要解决下,要根据创建实例的顺序进行解决。但是无论如何反射都可以访问到类的方法和变量,进行修改,所以非
    类加载这个时刻就把对象创建好的这种类,是不能防止反射攻击的。
    想要飞得更高,就该忘记地平线!
  • 相关阅读:
    Thread+Handler 线程 消息循环(转载)
    android开发之Fragment加载到一个Activity中
    Android应用程序框架之无边界设计意图
    windows系统下安装MySQL
    Java 性能优化技巧集锦
    功能完善的Java连接池调用实例
    Unicode 与 UTF 字符标准
    java内存配置
    Java Map 简介
    nginx 学习笔记(9) 配置HTTPS服务器--转载
  • 原文地址:https://www.cnblogs.com/shenwen/p/12676119.html
Copyright © 2020-2023  润新知