单例模式破解与防范

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

但是一般的我们这些写单例的时候可能都会忽略掉一些东西,导致单例代码的不严谨。

反射机制破解单例模式(枚举除外):

[Java] 纯文本查看 复制代码

?

01

02

03

04

05

06

07

08

09

10

11

12

13

14

public class BreakSingleton{

    public static void main(String[] args) throw Exception{

        Class clazz = Class.forName("Singleton");

        Constructor c = clazz.getDeclaredConstructor(null);

 

        c.setAccessible(true);

 

        Singleton s1 = c.newInstance();

        Singleton s2 = c.newInstance();

        //通过反射,得到的两个不同对象

        System.out.println(s1);

        System.out.println(s2);

    }

}


如何避免以上的漏洞:

[Java] 纯文本查看 复制代码

?

01

02

03

04

05

06

07

08

09

10

11

12

class Singleton{

    private static final Singleton singleton = new Singleton();

        private Singleton() {

        //在构造器中加个逻辑判断,多次调用抛出异常

        if(instance!= null){

            throw new RuntimeException()

        }

    }

    public static Singleton getInstance(){

        return singleton;

    }

}


反序列化机制破解单例模式(枚举除外):

[Java] 纯文本查看 复制代码

?

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

public class BreakSingleton{

 

  public static void main(String[] args) throws Exception{

 

     //先根据单例模式创建对象(单例模式所以s1,s2是一样的)

     Singleton s1=Singleton.getInstance();

     Singleton s2=Singleton.getInstance();

 

//将s1写入本地某个路径

     FileOutputStream fos=new FileOutputStream("本地某个路径下文件");

     ObjectOutputStream oos=new ObjectOutputStream(fos);

     oos.writeObject(s1);

     oos.close();

     fos.close();

 

//从本地某个路径读取写入的对象

     ObjectInputStream ois=new ObjectInputStream(new FileInputStream("和上面的本地参数路径相同"));

    Singleton s3=(Singleton) ois.readObject();

     System.out.println(s1);

     System.out.println(s2);

     System.out.println(s3);//s3是一个新对象

}

}


如何避免实现序列化单例模式的漏洞:

[Java] 纯文本查看 复制代码

?

01

02

03

04

05

06

07

08

09

10

11

12

13

14

class Singleton implements Serializable{

 

  private static final Singleton singleton = new Singleton();

 

  private Singleton() {

  }

  public static Singleton getInstance(){

         return singleton;

  }

//反序列化定义该方法,则不需要创建新对象

  private Object readResolve() throws ObjectStreamException{

    return singleton;

  }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值