在Spring中,Bean的scope属性中存在着两种模式既单例模式(singleton)和多例模式(prototype)。
singleton 单例模式: 对象在整个系统中只有一份,所有的请求都用一个对象来处理,如service和dao层的对象一般是单例的。
为什么使用单例:因为没有必要每个请求都新建一个对象的时候,因为这样会浪费CPU和内存。
prototype 多例模式:对象在整个系统中可以有多个实例,每个请求用一个新的对象来处理,如action。
为什么使用多例:防止并发问题;即一个请求改变了对象的状态,此时对象又处理另一个请求,而之前请求对对象的状态改变导致了对象对另一个请求做了错误的处理;
Spring bean 默认的是单例模式。
实例:我们先创建一个User类,类有id,name,password三个私有成员变量,生成他们的get和set方法。
package a_helloword.entity;
public class User {
private String id;
private String name;
private String password;
public void destroy(){
System.out.println("我销毁了");
}
public void init(){
//this.name="给不";
System.out.println("已经调用了初始化方法");
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password1) {
this.password = password1;
}
}
接下来在src下创建一个applicationContext.xml文件,该文件是用来配置Spring的
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd ">
<!--把User类放到容器中-->
<!--
bean:该元素需要Spring来管理,将User对象交给Spring管理
name: 给被管理的对象取一个名字,为了更方便的根据名字获得对象,用name的时候不能用特殊字符
id:和name的作用是一样的,使用name的话不能使用特殊字符。尽量使用name,
class:完整类名
scope: singleton:单例,prototype :多例
init-method:创建完成对象后,立即执行的方法
destroy-method:对象消亡的时候调用,Spring 容器关闭时会销毁所有的对象
-->
<bean id="user"
name="user"
class="a_helloword.entity.User"
scope="singleton"
init-method="init"
destroy-method="destroy"
></bean>
</beans>
接下来写一个测试类Demo 用来测试单例和多例模式的
package a_helloword.test;
import a_helloword.entity.User;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Demo {
@Test
public void fun(){
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("a_helloword/applicationContext.xml");
User user = (User) ac.getBean("user");
User user1 = (User) ac.getBean("user");
System.out.println(user);
System.out.println(user1);
//ac.close();
}
}
单例模式运行结果
已经调用了初始化方法
a_helloword.entity.User@51c8530f
a_helloword.entity.User@51c8530f
将配置文件中的singleton替换为prototype
多例模式的运行结果
已经调用了初始化方法
已经调用了初始化方法
a_helloword.entity.User@5891e32e
a_helloword.entity.User@cb0ed20
总结:从实例结果看出单例模式的输出结果指向同一个对象,而多例的指向了不同的对象,说明多例的从新创建了一个对象。