看完这篇Bean的作用域与生命周期,问到面试官不敢问--乐字节java
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了看完这篇Bean的作用域与生命周期,问到面试官不敢问--乐字节java相关的知识,希望对你有一定的参考价值。
Bean的作用域与生命周期
Bean的作用域
? 默认情况下,我们从Spring容器中拿到的对象均是单例的,对于bean的作用域类型如下:
singleton 作用域
? 注意: 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="prototype" 设置bean的类型 ,每次向Spring容器请求获取Bean都返回一个全新的Bean,相对于"singleton"来说就是不缓存Bean,每次都是一个根据Bean定义创建的全新Bean。
Web应用中的作用域
-
request作用域
表示每个请求需要容器创建一个全新Bean。比如提交表单的数据必须是对每次请求新建一个Bean来保持这些表单数据,请求结束释放这些数据。
-
session作用域
表示每个会话需要容器创建一个全新Bean。比如对于每个用户一般会有一个会话,该用户的用户信息需要存储到会话中,此时可以将该Bean作用域配置为session级别。
-
globalSession作用域
类似于session作用域,其用于portlet(Portlet是基于Java的Web组件,由Portlet容器管理,并由容器处理请求,生产动态内容)环境的web应用。如果在非portlet环境将视为session作用域。
? 配置方式和基本的作用域相同,只是必须要有web环境支持,并配置相应的容器监听器或拦截器从而能应用这些作用域,目前先熟悉概念,后续集成web时讲解具体使用,大家只需要知道有这些作用域就可以了。
如有疑问,可加入群:10803-55292,输入暗号13,即可有大佬帮助
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();
IOC/DI-控制反转和依赖注入
将对象实例化的创建过程转交给外部容器(IOC容器 充当工厂角色)去负责;属性赋值的操作;
以上是关于看完这篇Bean的作用域与生命周期,问到面试官不敢问--乐字节java的主要内容,如果未能解决你的问题,请参考以下文章
Android面试储备Activity知识点全家桶;看完这篇你还不会,请给我寄刀片
Android面试储备Activity知识点全家桶;看完这篇你还不会,请给我寄刀片
看完这一篇,再也不怕面试官问到IntentService的原理