IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> spring中bean的生命周期和作用域 -> 正文阅读

[Java知识库]spring中bean的生命周期和作用域

前言

bean的生命周期和作用域是面试题中经常会问到的问题,当然也不用去了解太深,过高的追求深度反而不好理解,但是一定要了解熟悉最基本的内容,我总结了一篇比较容易理解的版本,非常适合刚入门的新手去参考,本篇重点介绍了单例和原型模式下的bean的生命周期中不同过程的对比,也简单介绍了bean的六大作用域。


一、bean的生命周期

bean的生命周期简单地说就是对象从创建到销毁的过程,主要分为以下五个步骤:

1.调用无参构造创建对象

2.调用set方法初始化属性

3.调用bean的初始化方法

4.对象创建完成后,使用对象

5.关闭容器,调用销毁方法

不同模式下的bean创建对象的时机不同,bean主要有singleton和prototype两种类型。

?entity代码:

public class Student implements InitializingBean, DisposableBean {

    private String stuName;
    private  Integer age;
    public  Student(){
        System.out.println("无参构造被调用:Student()");
    }
    public String getStuName() {
        return stuName;
    }
    public void setStuName(String stuName) {
        System.out.println("set方法被调用:setStuName()");
        this.stuName = stuName;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        System.out.println("set方法被调用:setAge()");
        this.age = age;
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("对象初始化:interface afterPropertiesSet() ");
    }
     @Override
    public void destroy() throws Exception {
        System.out.println("对象销毁:interface destroy() ");
    }
}

Student实体类实现??InitializingBean, DisposableBean接口,可以自动创建重写的初始化方法和销毁方法。也可以不实现接口自定义初始化和销毁的方法。

singleton模式:

1.spring容器启动时会创建所有单例的bean

2.spring容器关闭时会调用所有的单例bean的销毁方法

3.singleton模式全局只会创建一个对象。

config.xml代码:

<bean id="student" class="spring.entity.Student" scope="singleton" init-method="afterPropertiesSet" destroy-method="destroy">

容器启动时 test代码:

public class SpringTest {
    @Test
      public void test1(){
        ClassPathXmlApplicationContext applicationContext =  new ClassPathXmlApplicationContext("applicationContext.xml");//容器启动
    }
}

运行结果:

?容器销毁时test代码:

public class SpringTest {
    @Test
      public void test1(){
        ClassPathXmlApplicationContext applicationContext =  new ClassPathXmlApplicationContext("applicationContext.xml");//启动容器
        Student student = applicationContext.getBean("student", Student.class);//获取容器
        System.out.println("student = " + student);
        applicationContext.close();//关闭容器
    }

?运行结果:

?容器每次获取时代码和运行结果:


public class SpringTest {
    @Test
      public void test1(){
        ClassPathXmlApplicationContext applicationContext =  new ClassPathXmlApplicationContext("applicationContext.xml");
        Student student = applicationContext.getBean("student", Student.class);
        Student student2 = applicationContext.getBean("student", Student.class);
        System.out.println(student==student2);
        applicationContext.close();
    }



运行结果:

无参构造被调用:Student()
set方法被调用:setStuName()
set方法被调用:setAge()
对象初始化:interface afterPropertiesSet() 
两次是否是同一个对象:
true
对象销毁:interface destroy() 

?所以单例模式下全局只会创建一个对象。

?prototype模式下:

1.在容器启动时不会创建对象,容器获取时才会创建对象。

2.容器关闭时不会调用销毁方法。

3.容器每获取一次创建一个对象。

config.xml代码:

<bean id="student" class="spring.entity.Student" scope="prototype" init-method="afterPropertiesSet" destroy-method="destroy">

容器启动时运行结果:?

?容器获取时test代码:

public class SpringTest {
    @Test
      public void test1(){
        ClassPathXmlApplicationContext applicationContext =  new ClassPathXmlApplicationContext("applicationContext.xml");//启动容器
        Student student = applicationContext.getBean("student", Student.class); //获取容器   
    }

?容器获取时和关闭时的运行结果:

容器每获取一次时的代码和运行结果:

public class SpringTest {
    @Test
      public void test1(){
        ClassPathXmlApplicationContext applicationContext =  new ClassPathXmlApplicationContext("applicationContext.xml");
        Student student = applicationContext.getBean("student", Student.class);
        Student student2 = applicationContext.getBean("student", Student.class);
        System.out.println(student==student2);
        applicationContext.close();
    }


运行结果:
第一次获取时:
无参构造被调用:Student()
set方法被调用:setStuName()
set方法被调用:setAge()
对象初始化:interface afterPropertiesSet() 
第二次获取时:
无参构造被调用:Student()
set方法被调用:setStuName()
set方法被调用:setAge()
对象初始化:interface afterPropertiesSet()
两次创建的是否是同一个对象: 
false

Process finished with exit code 0

?很显然prototype下每次获取都会创建不同的对象。

二、bean的六大作用域

作用域的种类

Spring 容器在初始化一个 Bean 实例时,同时会指定该实例的作用域。Spring 5 支持以下 6 种作用域。

1.singleton

默认值,单例模式,表示在 Spring 容器中只有一个 Bean 实例,Bean 以单例的方式存在。

<bean id="..." class="..." scope="singleton"/>

2.prototype

原型模式,表示每次通过 Spring 容器获取 Bean 时,容器都会创建一个 Bean 实例。

<bean id="..." class="..." scope="prototype"/>

3.request

每次 HTTP 请求,容器都会创建一个 Bean 实例。该作用域只在当前 HTTP Request 内有效。

4.session

同一个 HTTP Session 共享一个 Bean 实例,不同的 Session 使用不同的 Bean 实例。该作用域仅在当前 HTTP Session 内有效。

5.application

同一个 Web 应用共享一个 Bean 实例,该作用域在当前 ServletContext 内有效。

类似于 singleton,不同的是,singleton 表示每个 IoC 容器中仅有一个 Bean 实例,而同一个 Web 应用中可能会有多个 IoC 容器,但一个 Web 应用只会有一个 ServletContext,也可以说 application 才是 Web 应用中货真价实的单例模式。

6.websocket

websocket 的作用域是 WebSocket ,即在整个 WebSocket 中有效。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-07-04 22:41:24  更:2022-07-04 22:43:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 15:52:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码