Bean的作用域
singleton单例模式:使用此作用域时,Spring只会创建一个共享的bean实例,是Spring容器默认的作用域
prototype多例模式:使用此作用域时,Spring会为每个bean的请求都创建一个实例
- singleton和prototype是Spring常用的两个作用域,可以通过scope来指定作用域
<bean id="myFactory" class="com.robot.factory.MyFactory" scope="prototype"></bean
Bean的生命周期
Spring容器可以管理singleton作用域的Bean的生命周期,能够精确地知道该Bean何时被创建,何时初始化完成以及何时被销毁
对于prototype作用域的Bean的生命周期,Spring不会管理,而是由JVM去管理
- Spring使用饿汉式去创建实例,在Spring启动的时候,会将所有配置的bean都创建一个实例,而不是等到使用时才创建
- 提高程序运行效率。避免多次IO,减少对象创建时间
测试singleton作用域下的初始化和销毁
1、创建一个UserDao类
public class UserDao {
public void insert() {
System.out.println("execute insert...");
}
public void init() {
System.out.println("init...");
}
public void destroy() {
System.out.println("destroy...");
}
}
2、配置applicationContext.xml配置文件
- init-method方法指定初始化方法
- destroy-method方法指定销毁方法
<bean name="userDao" class="com.robot.dao.UserDao" init-method="init" destroy-method="destroy"></bean>
3、测试
- 使用后将容器关闭:关闭方法是ClassPathXmlApplicationContext类中才有,ApplicationContext中没有close()方法,所以可以直接用父类来创建对象
public class UserDaoTest {
@Test
public void userDaoTest() {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) applicationContext.getBean("userDao");
userDao.insert();
applicationContext.close();
}
}
输出结果
init...
execute insert...
destroy...
结果显示,在String容器初始化的时候,执行了init方法,然后调用insert方法,输出execute insert…,最后关闭Spring容器,执行destory方法
如果将scope更改为prototype作用域,则不会执行初始化和销毁方法
使用注解的方式,测试singleton作用域下的初始化和销毁
1、修改UserDao类
- @PostConstruct注解用于指定初始化方法
- @PreDestroy注解用于指定销毁方法
public class UserDao {
public void insert() {
System.out.println("execute insert...");
}
@PostConstruct
public void init() {
System.out.println("init...");
}
@PreDestroy
public void destroy() {
System.out.println("destroy");
}
}
2、修改applicationContext.xml配置文件
- 其中需要在beans中添加context(添加了三条)
- 因为使用了注解的方式,所以还需要配置包扫描context:component-scan
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="myFactory" class="com.robot.factory.MyFactory" scope="prototype"></bean>
<!-- <bean name="userDao" class="com.robot.dao.UserDao" init-method="init" destroy-method="destroy"></bean>-->
<context:component-scan base-package="com.robot.dao"></context:component-scan>
<bean name="userDao" class="com.robot.dao.UserDao"></bean>
</beans>
3、测试
public class UserDaoTest {
@Test
public void userDaoTest() {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) applicationContext.getBean("userDao");
userDao.insert();
applicationContext.close();
}
}
输出结果
init...
execute insert...
destroy...
结果显示,在String容器初始化的时候,执行了init方法,然后调用insert方法,输出execute insert…,最后关闭Spring容器,执行destory方法