看完这篇Bean的作用域与生命周期,问到面试官不敢问--乐字节java

118 篇文章 2 订阅

Bean的作用域与生命周期

Bean的作用域

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

singleton 作用域

Spring-09.png

注意: 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 作用域

​ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WGjNEVah-1594448809874)(E:/%E4%B9%90%E5%AD%97%E8%8A%82JavaWeb%E4%B8%AD%E7%BA%A7%E8%AF%BE%E7%A8%8B/day09/006_document/images/Spring-10.png)]

​ 通过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环境支持,并配置相应的容器监听器或拦截器从而能应用这些作用域,目前先熟悉概念,后续集成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容器 充当工厂角色)去负责;属性赋值的操作;

image

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值