一、懒汉式单例模式,解决反射和反序列化漏洞

package com.iter.devbox.singleton;

import java.io.ObjectStreamException;

import java.io.Serializable;

/**

* 懒汉式(如何防止反射和反序列化漏洞)

* @author Shearer

*

*/

public class SingletonDemo6 implements Serializable{

// 类初始化时,不初始化这个对象(延迟加载,真正用的时候再创建)

private static SingletonDemo6 instance;

private SingletonDemo6() {

// 防止反射获取多个对象的漏洞

if (null != instance) {

throw new RuntimeException();

}

}

// 方法同步,调用效率低

public static synchronized SingletonDemo6 getInstance() {

if (null == instance)

instance = new SingletonDemo6();

return instance;

}

// 防止反序列化获取多个对象的漏洞。

// 无论是实现Serializable接口,或是Externalizable接口,当从I/O流中读取对象时,readResolve()方法都会被调用到。

// 实际上就是用readResolve()中返回的对象直接替换在反序列化过程中创建的对象。

private Object readResolve() throws ObjectStreamException {

return instance;

}

}

package com.iter.devbox.singleton;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

public class Client2 {

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

SingletonDemo6 sc1 = SingletonDemo6.getInstance();

SingletonDemo6 sc2 = SingletonDemo6.getInstance();

System.out.println(sc1); // sc1,sc2是同一个对象

System.out.println(sc2);

// 通过反射的方式直接调用私有构造器(通过在构造器里抛出异常可以解决此漏洞)

/*Classclazz = (Class) Class.forName("com.iter.devbox.singleton.SingletonDemo6");

Constructorc = clazz.getDeclaredConstructor(null);

c.setAccessible(true); // 跳过权限检查

SingletonDemo6 sc3 = c.newInstance();

SingletonDemo6 sc4 = c.newInstance();

System.out.println(sc3); // sc3,sc4不是同一个对象

System.out.println(sc4);*/

// 通过反序列化的方式构造多个对象(类需要实现Serializable接口)

// 1. 把对象sc1写入硬盘文件

FileOutputStream fos = new FileOutputStream("object.out");

ObjectOutputStream oos = new ObjectOutputStream(fos);

oos.writeObject(sc1);

oos.close();

fos.close();

// 2. 把硬盘文件上的对象读出来

ObjectInputStream ois = new ObjectInputStream(new FileInputStream("object.out"));

// 如果对象定义了readResolve()方法,readObject()会调用readResolve()方法。从而解决反序列化的漏洞

SingletonDemo6 sc5 = (SingletonDemo6) ois.readObject();

// 反序列化出来的对象,和原对象,不是同一个对象。如果对象定义了readResolve()方法,可以解决此问题。

System.out.println(sc5);

ois.close();

}

}

二、静态内部类式单例模式(解决反射和反序列化漏洞)

package com.iter.devbox.singleton;

import java.io.ObjectStreamException;

import java.io.Serializable;

/**

* 静态内部类实现方式(也是一种懒加载方式)

* 这种方式:线程安全,调用效率高,并且实现了延迟加载

* 解决反射和反序列化漏洞

* @author Shearer

*

*/

public class SingletonDemo7 implements Serializable{

private static class SingletonClassInstance {

private static final SingletonDemo7 instance = new SingletonDemo7();

}

// 方法没有同步,调用效率高

public static SingletonDemo7 getInstance() {

return SingletonClassInstance.instance;

}

// 防止反射获取多个对象的漏洞

private SingletonDemo7() {

if (null != SingletonClassInstance.instance)

throw new RuntimeException();

}

// 防止反序列化获取多个对象的漏洞

private Object readResolve() throws ObjectStreamException {

return SingletonClassInstance.instance;

}

}

package com.iter.devbox.singleton;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

import java.lang.reflect.Constructor;

public class Client3 {

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

SingletonDemo7 sc1 = SingletonDemo7.getInstance();

SingletonDemo7 sc2 = SingletonDemo7.getInstance();

System.out.println(sc1); // sc1,sc2是同一个对象

System.out.println(sc2);

// 通过反射的方式直接调用私有构造器(通过在构造器里抛出异常可以解决此漏洞)

Classclazz = (Class) Class.forName("com.iter.devbox.singleton.SingletonDemo7");

Constructorc = clazz.getDeclaredConstructor(null);

c.setAccessible(true); // 跳过权限检查

SingletonDemo7 sc3 = c.newInstance();

SingletonDemo7 sc4 = c.newInstance();

System.out.println("通过反射的方式获取的对象sc3:" + sc3); // sc3,sc4不是同一个对象

System.out.println("通过反射的方式获取的对象sc4:" + sc4);

// 通过反序列化的方式构造多个对象(类需要实现Serializable接口)

// 1. 把对象sc1写入硬盘文件

FileOutputStream fos = new FileOutputStream("object.out");

ObjectOutputStream oos = new ObjectOutputStream(fos);

oos.writeObject(sc1);

oos.close();

fos.close();

// 2. 把硬盘文件上的对象读出来

ObjectInputStream ois = new ObjectInputStream(new FileInputStream("object.out"));

// 如果对象定义了readResolve()方法,readObject()会调用readResolve()方法。从而解决反序列化的漏洞

SingletonDemo7 sc5 = (SingletonDemo7) ois.readObject();

// 反序列化出来的对象,和原对象,不是同一个对象。如果对象定义了readResolve()方法,可以解决此问题。

System.out.println("对象定义了readResolve()方法,通过反序列化得到的对象:" + sc5);

ois.close();

}

}

java 防止反射_Java设计模式(一):单例模式,防止反射和反序列化漏洞相关推荐

  1. 3种设计模式java小程序_Java设计模式之单例模式(3种实现方式)

    饿汉模式 public class Singleton {//实例化private static Singleton instance=new Singleton();private Singleto ...

  2. java单例模式的七种写法_Java设计模式之单例模式的七种写法

    什么是单例模式? 单例模式是一种常见的设计模式,单例模式的写法有很多种,这里主要介绍三种: 懒汉式单例模式.饿汉式单例模式.登记式单例 . 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类 ...

  3. java connection 单例_Java设计模式之单例模式详解

    Java设计模式之单例模式详解 什么是设计模式 设计模式是在大量的实践中总结和理论之后优选的代码结构,编程风格,以及解决问题的思考方式.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可 ...

  4. java单例设计模式_Java设计模式之单例模式详解

    在Java开发过程中,很多场景下都会碰到或要用到单例模式,在设计模式里也是经常作为指导学习的热门模式之一,相信每位开发同事都用到过.我们总是沿着前辈的足迹去做设定好的思路,往往没去探究为何这么做,所以 ...

  5. filter java 是单例的吗_JAVA 设计模式之 单例模式详解

    单例模式:(Singleton Pattern)是指确保一个类在任何情况下都绝对只有一个实例,并提供一个全局访问点.单例模式是创建型模式.单例模式在现实生活中应用也非常广泛. 在 J2EE 标准中,S ...

  6. java设计模式在线视频_Java设计模式之单例模式视频课程

    一.概述 多例模式(Multiton  Pattern),这种设计模式也属于对象创建型模式,本质上就是单例模式的推广 定义: 一个类有多个实例且由类本身创建和管理自己的实例,并向外部提供访问点. 二. ...

  7. java 影子实例_java设计模式(四)--单例模式

    Singleton最熟悉不过了,下面学习单例模式.转载:http://zz563143188.iteye.com/blog/1847029 单例对象(Singleton)是一种常用的设计模式.在Jav ...

  8. java单例模式实例_Java设计模式之单例模式 通俗易懂 超详细 【内含案例】

    单例模式 什么是单例模式 ? 确保程序中一个类只能被实例化一次,实现这种功能就叫单例模式 单例模式的好处是什么 ? 方便控制对象 节省资源减少浪费 怎么实现单例模式 ? 构造私有化 调用静态方法返回实 ...

  9. java+单例+恶汉_Java设计模式之单例模式(恶汉式和懒汉式)

    /** 单例模式:* 饿汉式:类一加载就创建对象* 懒汉式:用的时候,才去创建对象* 面试题:单例模式的思想是什么?写一个代码体现(我们最好写懒汉式的单例模式给面 /* * 单例模式: *       ...

最新文章

  1. 美国年薪最高的高管是谁?彭博最新薪酬排名出炉,库克只排第二
  2. CUDA编程快速入门教程
  3. 有关于GB2312与Unicode的编码位
  4. Rest Framework:序列化组件
  5. Just another board game 博弈-vector套vector
  6. 快捷键截屏_关于Mac电脑截图,你必须要知道的几个快捷键!(错过会后悔哦)...
  7. LabVIEW2018安装教程
  8. 大四中软实习笔记20130226
  9. 将原生SQL功能Hibernate到您的Spring Data Repository中
  10. e站app改内置hosts_米家踢脚线电暖器E评测:符合现代家居审美 全屋取暖“小钢炮”...
  11. 公务员计算机考试题库,公务员考试题库
  12. java访问本地文件_java 读取本地文件 更改
  13. linux里的vmware16有中文吗,vmware 16.1专业版_linux版本下载_vmware 16.1下载_5分享
  14. 玩转springboot2.x之异步调用@Async
  15. 百度云文章的链接地址抓取工具
  16. python基础——经营第一个项目,如何将python学得更6 ?
  17. CSS3 3D旋转魔方
  18. 添加附件测试的测试点
  19. 阅读笔记0001之聊聊数据分析现状
  20. linux中sed如何替换换行符,linux sed命令,如何替换换行符“\n”

热门文章

  1. ActionTileViewController.js
  2. Price determination entry point - how is 4.85 calculated
  3. 关于CRM WebClient UI缓存清理的讨论
  4. Cloud for Customer里employee视图打开时的渲染逻辑
  5. 一个用Axure开发的安卓Android智能交通app的mockup
  6. Extension field添加到CDS view上的技术实现
  7. CM: UPDATE_PAYLOAD_FROM_ADDINSCH
  8. Java AOP研究之@Aspect注解的工作原理
  9. 你的ABAP程序给佛祖开过光么?来试试Jerry这个小技巧
  10. python 三维数据绘图_Python中三维坐标空间绘制的实现