您现在的位置是:首页 >学无止境 >Spring Bean的作用域及生命周期网站首页学无止境

Spring Bean的作用域及生命周期

小小太空人w 2023-06-18 20:00:03
简介Spring Bean的作用域及生命周期

目录

前言:

Bean的作用域(Scope)

单例模式

原型模式(多例作用域)

请求作用域(request)

会话作用域

全局作用域

网络长连接

Spring执行流程

Bean的生命周期

测试

小结:


前言:

    使用Spring框架时,我们需要清楚Spring托管Bean的作用域和生命周期,这样使用框架才会更加得心应手。

Bean的作用域(Scope)

单例模式

    singleton(默认模式),出于性能考虑,单例模式只需要实例一次即可(浅拷贝)。每次使用的都是同一个对象。

    该作用域的下的Bean在IoC容器中只存在一个实例。获取Bean,通过applicationContext.getBean()等方法获取,或者使用注解装配Bean(@Autowired注入)都是同一个对象实例。

    通常无状态的Bean使用该模式(无状态表示Bean对象的属性不需要更新)。Spring默认使用该模式。

原型模式(多例作用域)

    prototype(多例模式),每次使用对象都需要创建Bean对象,互相都没关系(深拷贝)。

    每次该作用域下的请求Bean对象实例都会创建新的Bean,类似于多例模式。获取Bean,通过applicationContext.getBean()等方法获取,或者使用注解装配Bean(@Autowired注入)都是新的对象实例。

    通常有状态的Bean使用该作用域,Bean的属性可能会更新。

请求作用域(request)

    每次HTTP请求,都会创建一个Bean对象(适用于 Spring MVC),类似于prototype模式。

    一次HTTP请求和响应是共享同一个Bean对象实例。

会话作用域

    每次Session会话共享一个Bean,例如记录用户的登录信息(适用于 Spring MVC)。在一个 http session 中,定义一个Bean实例。

全局作用域

    application,一个http servlet context 中共享同一个Bean(适用于 Spring MVC)。

    在一个http servlet context 中,定义一个Bean对象实例。Web应用的上下文信息,例如记录一个应用的共享信息。

网络长连接

    WebSocket,只适用于Spring WebSocket。在一个HTTP WebSocket的生命周期中(一次长连接),定义一个Bean实例。

    WebSocket的每次会话中,保存了一个Map结构的头信息,用来保存客户端消息头。第一次初始化后,直到一次长连接结束都是用一个Bean。

注意:

    可以在Spring配置文件中使用scpoe属性设置相应Bean的作用域。

Spring执行流程

    1)启动容器。加载配置文件,spring-config.xml文件。

    2)根据配置完成Bean实例化,初始化(分配内存空间,从无到有,初始化空间)。扫描配置文件下带有五大类或者方法注解,进行Bean初始化。

    3)注册Bean到Spring容器中。

    4)注入Bean的属性。(@Autowired@Resource)。

Bean的生命周期

    宏观上来谈,Bean的生命周期就是从诞生到销毁的过程。

1)开辟内存空间(实例化)

2)设置属性(注入属性)

3)初始化

  • 各种通知(对象的哪个属性初始化完成了)
  • 初始化前置方法
  • 初始化方法(两种实现方式:xml方式,注解方式)
  •  初始化后置方法

4)使用Bean

5)销毁Bean对象

注意:

    设置属性必须在初始化之前,因为有可能在初始化的时候使用Bean。

测试

package com.spring.demo.component;

import org.springframework.beans.factory.BeanNameAware;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

public class BeanComponent implements BeanNameAware {

    @Override
    public void setBeanName(String s) {
        System.out.println("执行了通知 -> " + s);
    }

    // xml初始化
    public void myInit() {
        System.out.println("xml方式初始化");
    }

    @PostConstruct
    public void doPostConstruct() {
        System.out.println("注解初始化");
    }

    public void hello() {
        System.out.println("hello");
    }

    @PreDestroy
    public void doPreDestroy() {
        System.out.println("执行了 doPreDestroy");
    }


}

    Spring配置文件,将Bean手动存储在Spring容器中。

<bean id="beanComponent" class="com.spring.demo.component.BeanComponent" init-method="myInit"></bean>

运行结果

注意:

    可以清楚看见Bean生命周期所做的一些事情(这里使用了两种初始化的方式)。

小结:

    Spring手动添加Bean和通过getBean()获取Bean的方式太麻烦,因此有了Spring Boot,就是Spring脚手架。目的就是更加方便的使用Spring容器,后续文章会详细介绍。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。