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

Bean作用域与生命周期

学习自省 2023-06-14 04:00:02
简介Bean作用域与生命周期

日升时奋斗,日落时自省 

目录

1、Bean的作用域问题

1.1、Lombok

1.2、修改Bean对象

2、作用域定义

2.1、Bean的6种作用域

2.1.1、singleton

2.1.2、prototype

2.1.3、request

2.1.4、session

2.1.5、appliction(了解)

2.1.6、websocket(了解)

2.2、设置作用域

 3、Spring执行流程和Bean的生命周求

3.1、Spring执行流程

 3.2、Bean生命周期

3.3、Bean生命周期演示

3.4、图解Bean生命周期


如果没有基本的Sping操作Maven的基础,可以先看一下下面的两篇博客 

Spring的创建和使用

使用注解添加Bean对象

此处相关的Bean作用域问题,来看Bean的作用域是怎么样的(我们从问题开始解析一个概念)

两个用户获取同一个对象对一个Bean对象进行修改或者查看,如果一个用户对Bean对象进行修改后,这个公共对象就会被修改,另一个用户访问接收到的信息就是更改后的,但是两个用户应该是不相重复的(就是你操作你的,我操作我的,互不影响)

1、Bean的作用域问题

 注:以上需要的这些前置操作的依赖,和配置文件都可以去前面的博客自取

1.1、Lombok

首先要先写一个用户吧,这里不白写,给友友们在介绍一个注解Lombok(以下有详细操作,需要下载一个插件)

 Lombok插件下载好了,引入依赖到pom.xml文件中的dependencies标签中

以上需要的操作都结束了,现在来创建一个实体类来使用Lombok中的注解(现在没有写获取属性的操作,一会bean对象获取就会进行此操作)

1.2、修改Bean对象

经过对象注入以后,两个Controllerle类就已经获取到了Bean对象了(相当于两个用户拿到了自己的页面,应该是各自操作各自的,互不影响)

接下来,我们写一下启动类,来看看是否会有我们想要的结果

 注:Bean作用域是Bean在Spring整个框架中的某种行为模式,比如当前使用的模式就是singleton单例作用域,Bean对象在Spring中只有一份,作用域全局,所有类都可以获取使用,其他人修改也就改变了(singleton也是Spring默认的行为模式)

2、作用域定义

作用域(scope)指的是在编程中,一段代码中变量、函数、对象等可被访问的范围。在不同的编程语言中,作用域的定义可能会有所不同,但是通常都是通过块级作用域或函数级作用域来实现的。作用域可以分为全局作用域和局部作用域,全局作用域中的变量可以在整个程序中被访问,而局部作用域中的变量只能在其定义的范围内被访问。

2.1、Bean的6种作用域

Spring容器在初始化一个Bean的实例时,同时会指定该实例的作用域,Spring有6种作用域

<1>singleton:单例作用域

<2>prototype:原型作用域(多例作用域)

<3>request:请求作用域

<4>session:会话作用域

<5>application:全局作用域

<6>websocket:HTTPWebSocket作用域

注:前两种作用域是针对普通的Spring项目,后4种针对SpringMVC

2.1.1、singleton

描述:在Spring IoC容器中的bean作用域,整个应用程序上下文中只有一个实例对象存在,整个应用程序上下文中只有一个实例对象存在,可以保证不同模块间使用的是同一个实例对象,提高程序的性能和效率

场景:通常无状态的Bean使用该作用域,无状态表示Bean对象的属性不需要更新

使用:Spring默认选择作用域

2.1.2、prototype

描述:Prototype是一种在Spring IoC容器中定义的bean作用域,它表示每次请求获取该bean时都会创建一个新的实例对象。也就是说,每次调用getBean()方法时,都会返回一个新的实例对象。

场景:Prototype作用域适用于需要频繁创建和销毁的对象,而且不需要共享状态的场景,通常有状态的Bean使用该作用域

使用:作用域普通的Spring中

2.1.3、request

描述:在Spring中,Bean定义为request作用域,表示该Bean只在当前HTTP请求中有效。这意味着,每次HTTP请求都会创建一个新的Bean实例,并且该实例仅在当前请求中有效。(类似于prototype)

场景:一次http的请求和响应的共享Bean,

使用:限定于SpringMVC中使用

2.1.4、session

描述:在Spring中,Bean定义为Session作用域,表示该Bean的生命周期与Web应用程序的Session周期相同。每个Session都会对应一个Session作用域的Bean实例,而且该实例在整个Session中都有效。

场景:Web应用的上下文信息,例如:一个登录信息(就是我们之前使用的Session)

使用:限定与SpringMVC中使用

2.1.5、appliction(了解)

描述:在http Servlet Context中定义一个Bean实例

场景:Web应用的上下文信息,例如:一个共享信息(独一份的)

使用:限定SpringMVC中使用

注:Application作用域的Bean实例在整个应用程序期间都有效,因此需要考虑线程安全的问题。另外,Application作用域的Bean实例占用内存较多,不适合用于保存大量数据或长时间运行的任务

2.1.6、websocket(了解)

描述:在一个http WebSocket的生命周期中,定义一个Bean实例

场景:Spring中没有WebSocket作用域,WebSocket是一种协议,用于在客户端和服务器之间建立双向通信通道。在Spring中,我们可以使用WebSocket来实现实时通信、推送消息等功能,但是并不存在WebSocket作用域的概念

使用:限定Spring webSocket中使用

2.2、设置作用域

刚刚写了两个用户,但是Spring作用域默认我是singleton单例作用域,现在设置作用域将每个用户的作用操作

 作用域更稳定的设置方法: 使用Spring自己提供的参数,我们手敲情况还是比较容易出错的

 3、Spring执行流程和Bean的生命周求

3.1、Spring执行流程

 3.2、Bean生命周期

生命周期是指一个事物在一定时间内经历的各个阶段或状态,所以Bean的生命周期就可以分为以下5个部分(也就是五个阶段,每个状态对应不同的状态)

<1>实例化Bean

过程:Spring会根据配置文件中的信息创建Bean的实例,为Bean对象分配内存空间

<2>设置属性

过程:Spring会将Bean的属性值设定到Bean实例中。属性值可以通过构造函数参数或者setter方法注入(对象注入)

<3>Bean初始化

初始化会完成三块:

I、初始化前置执行方法 (配置文件 可以设置,也可以使用)

II、初始化方法

III、初始化后置执行方法

<4>使用Bean(这一步可以算在周期内,比较实例Bean对象就是需要用的)

<5>销毁Bean

如何销毁:Spring会调用Bean的销毁方法,例如实现DisposableBean接口的destroy()方法或者使用@Bean注解的destroyMethod属性指定的自定义销毁方法

刚刚接触会有点抵触;

这里举一个事例来解释以上操作:人的一生(只是举例解释,不要自我带入)

<1>出生(实例化,从无到有)

<2>出生后上户口,名字,性别,家庭关系(设置属性)

<3>开始一系列成长学习(各种初始化)

<4>成人以后,开始正常生活,各种繁杂工作和事务(使用Bean)

<5>退休后(Bean销毁)

3.3、Bean生命周期演示

 BeanComponent类的代码:

public class BeanComponent implements BeanNameAware, InitializingBean, BeanPostProcessor  {
    //BeanNameAware 接口的中的方法重写 实例通知
    @Override
    public void setBeanName(String s) {
        System.out.println("执行通知 BeanName "+s);
    }
    // xml配置文件的初始化执行方法
    public void myInit(){
        System.out.println("xml 初识化方法");
    }
    //注解执行初始化方法方法
    @PostConstruct
    public void doPostConstruct(){
        System.out.println("注解的初识化方法");
    }
    //使用bean方法
    public void sayHi(){
        System.out.println("执行 sayHI()方法");
    }
    //Bean销毁方法  对应的一个注解 销毁
    @PreDestroy
    public void doPreDestroy(){
        System.out.println("doPreDestroy ...");
    }
    //前置初始化执行方法
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("前置执行方法");
    }
    //后置初始化执行方法
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("后置执行方法");
        return bean;
    }
}

注:这里加不加类注解都可以因为我们同时使用bean标签和content 标签注册Bean对象(如果对以上接口比较好奇的话,可以百度以下,作为了解,主要是为了Bean的生命周期)

运行结果:

 

这里不难发现初始化方法执行顺序:(这里了解一下就行)

@PostConstruct > init-method

3.4、图解Bean生命周期

注:以上接口或者方式不唯一,也不一定就只有上面这几种。 

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