提出问题
<bean id="UserSrvImpl" class="top.malaoshi.UserSrvImpl">
</bean>
在上面的配置中 什么时候创建的 top.malaoshi.UserSrvImpl 类对象,是单例 还是 多例模式,什么时候销毁的该对象?
这是本文要解决的问题
概述
本文介绍 spring <bean scope=""> 的 scope 属性
scope 属性非常重要,决定着 bean 对象的作用范围和生命周期
有以下几个值:
- singleton:单例模式,默认值(最常用)
- prototype:多例。每次都创建一个新对象(较常用)
- request:用于web项目,当有新的Http请求时,就会创建一个新对象,在该请求期间,是单例的
- session:用于web项目,当有新的Http session时,就会创建一个新对象,在当前session期间,是单例的
- global-session:用于web项目,应用在集群,全局session。
不是集群时,功能同session。
singleton
单例模式,默认值(最常用)
生命周期:
- 创建:spring容器创建时,就开始创建该对象
- 生存:只要容器在,对象一直活着
- 死亡:容器销毁时,对象就销毁了
体验
spring.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="UserSrvImpl" class="top.malaoshi.UserSrvImpl">
</bean>
</beans>
没有 scope 属性,即:默认为 单例模式
UserSrvImpl如下:
public class UserSrvImpl implements IUserService {
public UserSrvImpl(){
System.out.println("UserSrvImpl构造方法");
}
public void save(String username,String password){
System.out.println("保存 "+username+","+password+" 成功!");
}
}
增加默认构造方法,并且打印一段文字
主启动类:
public class Main {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("spring.xml");
IUserService srv=(IUserService)ac.getBean("UserSrvImpl");
IUserService srv2=(IUserService)ac.getBean("UserSrvImpl");
System.out.println(srv==srv2);
}
}
执行结果:
UserSrvImpl构造方法
true
在主启动类中调用了 2 次 ac.getBean("UserSrvImpl") ,但只打印了一次 UserSrvImpl构造方法,说明只调用了一次 UserSrvImpl 构造方法,所以 srv==srv2 为 true
prototype
多例。每次都创建一个新对象(较常用)
生命周期:
- 创建:当使用对象时,创建新的对象实例。
- 生存:只要对象在使用中,就一直活着。
- 死亡:由 java 垃圾回收器回收
体验
spring.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="UserSrvImpl" class="top.malaoshi.UserSrvImpl" scope="prototype">
</bean>
</beans>
增加 scope="prototype" ,即:多例模式
UserSrvImpl如下:
public class UserSrvImpl implements IUserService {
public UserSrvImpl(){
System.out.println("UserSrvImpl构造方法");
}
public void save(String username,String password){
System.out.println("保存 "+username+","+password+" 成功!");
}
}
增加默认构造方法,并且打印一段文字
主启动类:
public class Main {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("spring.xml");
IUserService srv=(IUserService)ac.getBean("UserSrvImpl");
IUserService srv2=(IUserService)ac.getBean("UserSrvImpl");
System.out.println(srv==srv2);
}
}
执行结果:
UserSrvImpl构造方法
UserSrvImpl构造方法
false
在主启动类中调用了 2 次 ac.getBean("UserSrvImpl") ,打印了 两次 UserSrvImpl构造方法 ,说明调用了两次 UserSrvImpl 构造方法,创建了2个对象,所以 srv==srv2 为 false
