在Spring中Bean有五个作用域,其中singleton和prototype分别是单例模式和原型模式。
这里讲一下单例模式和原型模式,进行整理方便我复习。
spring中bean的创建实际就是两种:单例模式和原型模式。(原型模式需要和工厂模式搭配起来)
一、原型模式
原型模式是23种设计模式的其中一种。
在创建对象时通过new关键字创建的对象 (类加载判断,内存分配,初始化等),在我们需要大量对象时所消耗的时长会较长影响性能,原型模式相对于通过一个个去new对象而言,消耗较低。
原型模式我们也称为克隆模式,即一个某个对象为原型克隆出来一个一模一样的对象,该对象的属性和原型对象一模一样。而且对于原型对象没有任何影响。
原型模式的克隆方式有两种:浅克隆和深度克隆。
浅克隆:只是拷贝本对象,其对象内部的数组、引用对象等都不拷贝,还是指向原生对象的内部元素地址。
浅克隆仅仅复制所考虑的对象,而不复制它所引用的对象。只拷贝本对象,对其对象内部所有的其他引用对象以及数组等不进行拷贝,它们还是指向原来地址。Object类提供的方法clone只是拷贝本对象 , 其对象内部的数组、引用对象等都不拷贝,还是指向原生对象的内部元素地址。
深克隆:深复制把要复制的对象所引用的对象都复制了一遍。
拷贝需要实现Cloneable, Serializable两个接口,重写clone方法
//浅拷贝
Pojo类:
public class User implements Cloneable, Serializable {
private String name;
private Date date;
public User() {
super();
// TODO Auto-generated constructor stub
}
public User(String name, Date date) {
super();
this.name = name;
this.date = date;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
@Override
public Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}
}
测试:
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
System.out.println("---初始化---");
User user = new User();
Date date = new Date(1231231231231l);
user.setName("zsl");
user.setDate(date);
System.out.println("user name:"+user.getName());
System.out.println("user date:"+user.getDate());
System.out.println("user:"+user);
System.out.println("----修改时间----");
date.setTime(123231231231l);
user.setDate(date);
System.out.println("修改后user中date:"+user.getDate());
System.out.println("----进行浅克隆----");
User user1 = (User) user.clone();
user1.setName("zsl666");
System.out.println("user1中name:"+user1.getName());
System.out.println("user1 date:"+user1.getDate());
System.out.println("user1:"+user1);
}
}
//深克隆有两种方式:
//1、基于浅拷贝,重写clone方法把对象里所引用的对象全部复制
//2、使用序列化与反序列化进行深拷贝
1、基于浅拷贝实现深拷贝
Pojo类:
public class User implements Cloneable, Serializable {
private String name;
private Date date;
public User() {
super();
// TODO Auto-generated constructor stub
}
public User(String name, Date date) {
super();
this.name = name;
this.date = date;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
@Override
public Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stu
Object object = super.clone();
User user= (User) object;
user.date= (Date) this.date.clone();
return object;
}
}
测试:
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
System.out.println("---初始化---");
User user = new User();
Date date = new Date(1231231231231l);
user.setName("zsl");
user.setDate(date);
System.out.println("user name:"+user.getName());
System.out.println("user date:"+user.getDate());
System.out.println("user:"+user);
User user1 = (User) user.clone();
System.out.println("----修改时间----");
date.setTime(123231231231l);
// user.setDate(date);
System.out.println("修改后user中date:"+user.getDate());
System.out.println("----进行深克隆----");
user1.setName("zsl666");
System.out.println("user1中name:"+user1.getName());
System.out.println("user1 date:"+user1.getDate());
System.out.println("user1:"+user1);
}
}
2、使用序列化和反序列化进行深拷贝
Pojo类:
package com.zsl.pojo;
import java.io.Serializable;
import java.util.Date;
public class User implements Cloneable, Serializable {
private String name;
private Date date;
public User() {
super();
// TODO Auto-generated constructor stub
}
public User(String name, Date date) {
super();
this.name = name;
this.date = date;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
@Override
public Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}
}
测试:
public class Test2 {
public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException {
System.out.println("---初始化---");
User user = new User();
Date date = new Date(1231231231231l);
user.setName("zsl");
user.setDate(date);
System.out.println("user name:"+user.getName());
System.out.println("user date:"+user.getDate());
System.out.println("user:"+user);
//序列化:把对象转换为字节序列的过程。
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(user);
byte[] bs = bos.toByteArray();
//反序列化:把字节序列恢复为对象的过程。
ByteArrayInputStream bis = new ByteArrayInputStream(bs);
ObjectInputStream ois = new ObjectInputStream(bis);
User user1 = (User) ois.readObject();
System.out.println("----进行深克隆----");
user1.setName("zsl666");
System.out.println("user1中name:"+user1.getName());
System.out.println("user1 date:"+user1.getDate());
System.out.println("user1:"+user1);
}
}
通过clone的方式在获取大量对象的时候性能开销基本没有什么影响,而new的方式随着实例的对象越来越多,性能会急剧下降,所以原型模式是一种比较重要的获取实例的方式。
原型模式很少单独出现,一般是和工厂方法模式一起出现,通过clone的方法创建一个对象,然后由工厂方法提供给调用者。
二、单例模式
下回补上,哈哈….