Bean的作用域和生命周期

Bean的作用域和生命周期

Bean的作用域

默认情况下,我们从Spring容器中拿到的对象均是单例的,对于bean的作⽤域类型如下:

singleton 单例作用域

bean被实例化后会放置到单例缓存池中,每次获取的都是同一个bean对象。
在这里插入图片描述

注意:lazy-init是懒加载, 如果等于true时作用是指Spring容器启动的时候不会去实例化这个bean, ⽽是在程序调用时才去实例化. 默认是false,即Spring容器启动时实例化。

默认情况下,被管理的bean只会在IOC容器中存在一个实例,对于所有获取该Bean的操作Spring容器将返回同一个Bean。

容器在启动的情况下就实例化所有singleton的bean对象,并缓存到容器中。

lazy-init 属性(懒加载)

如果为false,则在IOC容器启动时会实例化bean对象,默认false。
如果为true,则IOC容器启动时不会实例化Bean对象,在使用bean对象时才会实例化。

lazy-init 设置为false有什么好处?

1.可以提前发现潜在的配置问题;
2.Bean对象存在于缓存中,使用时不用再去实例化bean,加快程序运行程序。

什么对象适合作为单例对象?

一般来说对于无状态或状态不可改变的对象适合使用单例模式。(不存在会改变对象状态的成员变量)

比如:controller层、service层、dao层

什么是无状态或者状态不可改变的对象?

实际上对象状态的变化往往均是由于属性值的变化而引起的,比如User类,姓名属性会有变化,属性姓名的变化一般会引起user对象状态的变化。对于程序来说,无状态对象没有实例变量的存在,保证了线程的安全性,service层业务对象即是无状态对象,是线程安全的。

prototype 原型作用域

通过scope属性设置

每次实例化时都是一个全新的bean对象。
在这里插入图片描述

通过scope=“prototype” 设置bean的类型 ,每次向Spring容器请求获取Bean都返回⼀个全新的Bean,相对于"singleton"来说就是不缓存Bean,每次都是⼀个根据Bean定义创建的全新Bean。

Web应用中的作用域

1.request作用域

表示每个请求都需要容器来创建⼀个全新的Bean。比如提交表单的数据必须是对每次请求新建⼀个Bean来保持这些表单数据,请求结束释放这些数据。

2.session作用域

表示每个会话需要容器创建⼀个全新Bean。⽐如对于每个⽤户⼀般会有⼀个会话,该⽤户的⽤户信息需要存储到会话中,此时可以将该Bean作⽤域配置为session级别。

3.globalSession作用域

类似于session作⽤域,其⽤于portlet(Portlet是基于Java的Web组件,由Portlet容器管理,并由容器处理请求,⽣产动态内容)环境的web应⽤。如果在⾮portlet环境将视为session作⽤域。

配置方式和基本的作用域相同,只是必须要有web环境的支持,并配置相应的容器监听器或拦截器从而能应用这些作用域。

Bean的生命周期

对比已经学过的servlet ⽣命周期(容器启动装载并实例化servlet类,初始化servlet,调用service⽅法,销毁servlet)。
同样对于Spring容器管理的bean也存在生命周期的概念。

在Spring中,Bean的⽣命周期包括Bean的定义、初始化、使⽤和销毁4个阶段。

Bean的定义

在Spring中,通常是通过配置⽂档的⽅式来定义Bean的。

在⼀个配置⽂档中,可以定义多个Bean。

Bean 的初始化

默认在IOC容器加载时,实例化对象。

Spring Bean初始化有两种方式:

方式一:在配置文档中指定 init-method属性来完成。

public class RoleService{
    
    
	//定义初始化时需要被调用的方法
	public void init(){
    
    
		System.out.println("RoleService init ...");
	}
}
<!--通过init-method属性制定方法-->
<bean id="roleService" class="com.xxxx.service.RoleService" init-method="init"></bean>

方式二:实现 org.springframework.beans.factory.InitializingBean 接⼝。

public class RoleService implements InitializingBean {
    
    
	@Override
	public void afterPropertiesSet() throws Exception {
    
    
		System.out.println("RoleService init...");
	}
}
<bean id="roleService" class="com.xxxx.service.RoleService" ></bean>

Bean对象实例化过程是在Spring容器初始化时被实例化的,但也不是不可改变的,可以通过 lazy-init=“true” 属性延迟bean对象的初始化操作,此时再调用getBean 方法时才会进行bean的初始化操作。

Bean 的使用

方式一:使用BeanFactory

// 得到Spring的上下⽂环境
BeanFactory factory = new ClassPathXmlApplicationContext("spring.xml");
RoleService roleService = (RoleService) factory.getBean("roleService");

方式二:使用ApplicationContext

// 得到Spring的上下⽂环境
ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
RoleService roleService = (RoleService) ac.getBean("roleService");

Bean的销毁

实现销毁方式(Spring容器会维护bean对象的管理,可以指定bean对象的销毁所要执行的方法)。

步骤⼀:实现销毁方式(Spring容器会维护bean对象的管理,可以指定bean对象的销毁所要执行的方法)

<bean id="roleService" class="com.xxxx.service.RoleService" destroy-method="destroy"></bean>

步骤二:通过 AbstractApplicationContext 对象,调用其close方法实现bean的销毁过程,关闭容器。

AbstractApplicationContext ctx=new ClassPathXmlApplicationContext("spring.xml");
ctx.close();

猜你喜欢

转载自blog.csdn.net/lln1540295459/article/details/121115236