Spring6 当中 Bean 的生命周期的详细解析:有五步,有七步,有十步

1. Spring6 当中 Bean 的生命周期的详细解析:有五步,有七步,有十步

文章目录

  • 1. Spring6 当中 Bean 的生命周期的详细解析:有五步,有七步,有十步
  • 每博一文案
    • 1.1 什么是 Bean 的生命周期
    • 1.2 Bean 的生命周期 "五步"
    • 1.3 Bean 的生命周期 “七步”
    • 1.4 Bean 的生命周期 “十步”
  • 2. Bean的作用域不同,管理方式也将是不同的
    • 2.1 自己new的对象让Spring管理
  • 3. 总结:
  • 4. 最后:


每博一文案

“这个世界本来就是这样的,会认识形形色色的人,会遇到无法理解的恶意,
会感到失望,但是只要过去了,你就会发现,那些带着偏见自说自话的言论,
还有那些不能理解的恶意,都是在提醒我们不要成为那样的人。
或许会焦虑,会不知所措,生活也不太如意,会感到绝望。但我想说:前路漫漫,需自身强大。”世界就是如此复杂,生活也从不是尽如人意,但我还是希望你,
即使见过那些肮脏与不堪,也依然能保有一颗温良的心。深渊可以凝视,但不要驻足。只要心存光明,世界就不黑暗。

1.1 什么是 Bean 的生命周期

Spring 其实就是一个管理 Bean 对象的工厂。它负责对象的创建,对象的销毁等。

所谓的生命周期:简单的来说:就是一个对象从创建开始到最终销毁的整个过程。

  • 什么时候创建Bean 对象 ?
  • 创建 Bean 对象的前后会调用什么方法?
  • Bean 对象什么时候销毁?
  • Bean 对象的在销毁前后会调用生命方法?

那么我们为什么要知道 Bean 的生命周期呢?

其实生命周期的本质是:在哪个时间节点上调用了哪个类当中的哪个方法。

我们需要充分的了解在这个生命线当中,都有哪些特殊的时间节点。

只有我们知道了特殊的时间节点都在哪里了,这样我们才可以确定代码的对应上需要该写到哪里。

有时,我们可能需要在某个特殊的时间点上执行一段特定的代码,从而满足我们的需求,而这段代码可以放到哪个节点上,当生命线走到这里的时候,自然会被调用。

1.2 Bean 的生命周期 “五步”

关于 Bean 生命周期的管理,我们可以参考Spring的源码的:AbstractAutowireCapableBeanFactory类的doCreateBean()方法。 想要进一步了解该源码内容的大家可以移步至✏️✏️✏️Spring6 当中的 Bean 循环依赖的详细处理方案+源码解析-CSDN博客

这里的 Bean的生命周期“五步”是最基本,比较粗略的五步。

  1. 第一步:实例化 Bean
  2. 第二步:对 Bean 当中的属性进行赋值
  3. 第三步:初始化 Bean
  4. 第四步:使用 Bean
  5. 第五步:销毁 Bean

在这里插入图片描述

注意点:

  1. 其中的:第三步:初始化 Bean 需要我们通过在 spring.xml 配置文件当中的 标签当中通过 init-method= 属性指定初始化方法 是哪一个方法
  2. 其中的:第四步:销毁 Bean 也是需要我们通过在 spring.xml 配置文件当中的 标签当中的 destroy-method=性指定销毁方法 是哪个方法

实践测试:

准备工作:配置导入 相关的 spring 框架,让 Maven 帮我们导入 spring的相关jar包

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.rainbowsea</groupId><artifactId>spring6-006-bean-lifecycle-blog</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target></properties><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.0.11</version></dependency><!-- junit4 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency></dependencies></project>

第一步: 定义一个 Bean 对象类,这里我们就定义一个 User 的类,来进行测试。

在这里插入图片描述

在这里插入图片描述

package com.rainbowsea.bean;public class User {private String name;public User() {System.out.println(" 第一步: User 无参数构造方法调用");}public User(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;System.out.println("第二步: 为 User 这个 Bean 进行赋值操作");}/*** 这个方法需要自己写,方法名随意,但是注意写好之后,要通过init-method 配给Spring框架,让其知道这个东东*/public void initUserBean() {System.out.println("第三步: 对 User Bean 对象进行一个初始化操作");}/*** 这个方法需要自己写,方法名随意,但是注意写好之后,要通过destroy-method配给Spring框架,让其知道这个东东*/public void destroyUserBean() {System.out.println("第五步: 对 User Bean 对象进行一个销毁操作");}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +'}';}
}

第二步: 配置相关的 spring.xml 告诉 Spring 框架要做的事情。

在这里插入图片描述

上面我们说到,注意点是:

  1. 其中的:第三步:初始化 Bean 需要我们通过在 spring.xml 配置文件当中的 标签当中通过 init-method= 属性指定初始化方法 是哪一个方法
  2. 其中的:第四步:销毁 Bean 也是需要我们通过在 spring.xml 配置文件当中的 标签当中的 destroy-method=性指定销毁方法 是哪个方法

在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!--init-method指明Bean的初始化方法是哪个;destroy-method指明Bean的销毁方法是哪个    --><bean id="userBean" class="com.rainbowsea.bean.User" init-method="initUserBean" destroy-method="destroyUserBean"><property name="name" value="张三"></property> <!--set注入赋值--></bean>
</beans>

第三步: 运行客户端,模拟测试

注意点:

我们需要手动调用 ClassPathXmlApplicationContext类下面的 close() 方法,正常关闭spring容器才会执行销毁方法。

在这里插入图片描述
在这里插入图片描述

package com.rainbowsea.test;import com.rainbowsea.bean.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class BeanLifecycleTest {@Testpublic void testRegisterBean() {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring6.xml");User userBean = applicationContext.getBean("userBean", User.class);System.out.println("第四步: 使用 User Bean 对象" + userBean);ClassPathXmlApplicationContext classPathXmlApplicationContext = (ClassPathXmlApplicationContext) applicationContext;// 注意点:这里的 close()方法是,ClassPathXmlApplicationContext 类才有的,它的ApplicationContext 父类没有。// 父类无法调用子类特有的方法,所以这里我们需要强制类型转换回来(向下转型),为子类// 只有正常关闭spring容器才会执行销毁方法classPathXmlApplicationContext.close();}
}

执行结果:

在这里插入图片描述

总结注意点:

    1. 第一:配置文件中的init-method指定初始化方法。destroy-method指定销毁方法
    2. 第二:只有正常关闭spring容器,bean的销毁方法才会被调用。
    3. 第三:ClassPathXmlApplicationContext类才有close()方法。

1.3 Bean 的生命周期 “七步”

Bean 的生命周期分为“七步”: 是在五步的当中的:第三步初始化Bean 的前后添加上的,Bean 的后处理器。如果加上 Bean 后处理器的话,Bean 的生命周期就是 七步了。

具体七步如下:

  1. 第一步:实例化 Bean
  2. 第二步:对 Bean 当中的属性进行赋值
  3. 第三步:执行 Bean 后处理器的 befor() 方法执行,具体的是:postProcessBeforeInitialization(Object bean, String beanName) 方法
  4. 第四步:初始化 Bean
  5. 第五步:执行 Bean 后处理器的 after() 方法执行,具体的是 postProcessAfterInitialization(Object bean, String beanName) 方法
  6. 第六步:使用 Bean
  7. 第七步:销毁 Bean

在这里插入图片描述

第一步:关于 Bean 的后处理器的编写:

关于: bean的后处理器的编写:

编写 bean 后处理器,就是让一个类实现 implements BeanPostProcessor 接口类,同时并且重写其中的before(postProcessBeforeInitialization())和after(postProcessAfterInitialization())方法:

在这里插入图片描述
BeanPostProcessor 接口有,两个默认的方法,这两个方法,便是我们需要重写的,来实现我们自己的要的功能。

@Nullable
// 在 Bean 初始化之前被调用default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}@Nullable
// 在 Bean 初始化之后就被调用default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}

其中两个参数的作用含义分别是:

在这里插入图片描述

    1. Object bean 是该对应的 bean 的对象
    2. String beanName 是该对应 bean 的在spring.xml配置文件当中 id的名字。

    在这里插入图片描述

这里我们定义一个MyBeanPostProcessor 类作为 Bean 后处理器 实现该 implements BeanPostProcessor 接口,并重写其中的两个默认方法。

在这里插入图片描述

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;public class MyBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {// Object bean 是 该对应的 bean 的对象// String beanName 是该对应 bean 的在配置文件当中 idSystem.out.println("第三步:  Bean 初始化之前执行before()方法");return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {// Object bean 是 该对应的 bean 的对象// String beanName 是该对应 bean 的在配置文件当中 idSystem.out.println("第五步:  Bean 初始化之后执行after() 方法");return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);}
}

第二步:将 Bean 后处理器配置到 spring.xml 文件当中去,告知 Spring 框架,同时进行管理。

在这里插入图片描述

大家需要注意的是:该配置Bean后处理器。这个后处理器将作用于当前整个配置文件中所有的bean。

在这里插入图片描述

也就是作用于当前这个名为 “spring6.xml” 文件当中的,所配置的所有 bean 都会自动使用上这个我们配置的 bean 后处理器。关于这一点具体说明。我们后面会详细说明的,大家放心。

第三步:模拟客户端,执行程序:

在这里插入图片描述


import com.rainbowsea.bean.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class BeanLifecycleTest {@Testpublic void testRegisterBean() {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring6.xml");User userBean = applicationContext.getBean("userBean", User.class);System.out.println("第六步: 使用 User Bean 对象" + userBean);ClassPathXmlApplicationContext classPathXmlApplicationContext = (ClassPathXmlApplicationContext) applicationContext;// 注意点:这里的 close()方法是,ClassPathXmlApplicationContext 类才有的,它的ApplicationContext 父类没有。// 父类无法调用子类特有的方法,所以这里我们需要强制类型转换回来(向下转型),为子类// 只有正常关闭spring容器才会执行销毁方法classPathXmlApplicationContext.close();}
}

上面我们提到了**“这个 bean 后处理器的是作用于整个对应的 spring.xml 的配置文件上的所有的 Bean”** 的关于这一点,我们下面进行一个简单的验证一下。

我们再创建一个空的类,然后进行一个构造方法的注入,交给 Spring 框架进行管理,是否还是会执行 Bean 处理器。

在这里插入图片描述
在这里插入图片描述

运行测试:在这里插入图片描述

从运行结果上看,我们可以明显的看出。这个Bean 后处理器是,作用于此 spring.xml 当中对应的整个 Bean 对象的 。简单的来说:就是只要你在某个其中的 spring.xml配置文件当中,启动了,并配置了对应的 Bean后处理器,那么整个 spring.xml 配置文件当中的所有的 Bean 对象都会自动启动上该 Bean 后处理器。

1.4 Bean 的生命周期 “十步”

Bean的生命周期的“十步”就是更加的细化了 。更加的灵活了 。

让我们一起来看一下,这所谓的十步,是在上面的七步当中的哪些节点当中,增加了那另外的三步。

十步是在下面这些位置,增加了另外的三步

  1. 首先在 Bean 后处理器的 befor ()执行的前后各自增加了一步,总共为两步
    1. Bean 后处理器的 befor()执行前,增加了 检查 Bean 是否实现了 Aware 的相关接口,并设置相关依赖。
    2. Bean 后处理器的 befor()执行后,增加了检查 Bean 是否实现了 InitializingBean 接口,并调用接口当中的方法 。
  2. 最后一步,添加在了 销毁 Bean 之前,增加了检查 Bean 是否实现了 DisposableBean 接口,并调用接口当中的方法。

具体十步如下:

  1. 第一步:实例化 Bean
  2. 第二步:对 Bean 当中的属性进行赋值
  3. 第三步: 检查 Bean 是否实现了 Aware 的相关接口,并设置相关依赖。
    1. 其中Aware 的相关接口有三个分别是:BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
  4. 第四步:执行 Bean 后处理器的 befor() 方法执行,具体的是:postProcessBeforeInitialization(Object bean, String beanName) 方法
  5. 第五步:检查 Bean 是否实现了 InitializingBean 接口,并调用接口当中的方法 。
  6. 第六步:初始化 Bean
  7. 第七步:执行 Bean 后处理器的 after() 方法执行,具体的是 postProcessAfterInitialization(Object bean, String beanName) 方法
  8. 第八步:使用 Bean
  9. 第九步:检查 Bean 是否实现了 DisposableBean 接口,并调用接口当中的方法。
  10. 第十步:销毁 Bean

在这里插入图片描述

补充说明:

Aware相关的接口包括:BeanNameAware、BeanClassLoaderAware、BeanFactoryAware

  • 当Bean实现了BeanNameAware,对应的方法是setBeanName(String name) :Spring会将Bean的名字传递给Bean。

  • 当Bean实现了BeanClassLoaderAware,对应的方法是setBeanClassLoader(ClassLoader classLoader) ; Spring会将加载该Bean的类加载器传递给Bean。

  • 当Bean实现了BeanFactoryAware,对应的方法是setBeanFactory(BeanFactory beanFactory); Spring会将Bean工厂对象传递给Bean。

  • 在这里插入图片描述
    InitializingBean 接口下对应的是:afterPropertiesSet () 方法。

  • 在这里插入图片描述
    DisposableBean 接口下的对应的是:destroy() 方法。

在这里插入图片描述

  • 测试以上10步,需要让User类实现5个接口,并实现其中的所有方法:

    • BeanNameAware

    • BeanClassLoaderAware

    • BeanFactoryAware

    • InitializingBean

    • DisposableBean

第一步:定义 Bean 类,我们还是使用这个 User 空白类,进行测试。

第二步:让 让User类实现5个接口(BeanNameAware,BeanClassLoaderAware,BeanFactoryAware,InitializingBean,DisposableBean),并实现其中的所有方法:

在这里插入图片描述

package com.rainbowsea.bean;import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;public class User implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware, InitializingBean, DisposableBean {private String name;public User() {System.out.println("第一步: User 无参数构造方法调用");}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("第五步:检查Bean是否实现了InitializingBean 接口,并调用接口方法.afterPropertiesSet执行");}@Overridepublic void destroy() throws Exception {System.out.println("第九步: 检查 Bean是否实现了DisposableBean接口,并调用接口方法 destroy()  ");}@Overridepublic void setBeanClassLoader(ClassLoader classLoader) {System.out.println("第三步:检查是否实现了Aware的相关接口并调用其中的实现接口方法(): Bean 这个类的加载器" + classLoader);}@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {System.out.println("第三步:检查是否实现了Aware的相关接口并调用其中的实现接口方法():  生产这个Bean的工厂对象是 " +beanFactory);}@Overridepublic void setBeanName(String name) {System.out.println("第三步:检查是否实现了Aware的相关接口并调用其中的实现接口方法():  这个Bean的名称是: " + name);}public User(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;System.out.println("第二步: 为 User 这个 Bean 进行赋值操作");}/*** 这个方法需要自己写,方法名随意,但是注意写好之后,要通过init-method 配给Spring框架,让其知道这个东东*/public void initUserBean() {System.out.println("第六步: 对 User Bean 对象进行一个初始化操作");}/*** 这个方法需要自己写,方法名随意,但是注意写好之后,要通过destroy-method配给Spring框架,让其知道这个东东*/public void destroyUserBean() {System.out.println("第十步: 对 User Bean 对象进行一个销毁操作");}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +'}';}}

配置的 spring.xml 文件信息不变:保持和生命周期“七步”是一样的,因为十步是基于七步的基础上细化,添加的。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!--配置Bean后处理器。这个后处理器将作用于当前配置文件中所有的bean。--><bean class="com.rainbowsea.bean.MyBeanPostProcessor"/><!--init-method指明Bean的初始化方法是哪个;destroy-method指明Bean的销毁方法是哪个    --><bean id="userBean" class="com.rainbowsea.bean.User" init-method="initUserBean" destroy-method="destroyUserBean"><property name="name" value="张三"></property> <!--set注入赋值--></bean></beans>

对应的 Bean 后处理也是不变的(和生命周期七步是一样的),因为十步是基于七步的基础上细化,添加的。

package com.rainbowsea.bean;import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;public class MyBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {// Object bean 是 该对应的 bean 的对象// String beanName 是该对应 bean 的在配置文件当中 idSystem.out.println("第四步:  Bean 初始化之前执行before()方法");return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {// Object bean 是 该对应的 bean 的对象// String beanName 是该对应 bean 的在配置文件当中 idSystem.out.println("第七步:  Bean 初始化之后执行after() 方法");return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);}
}

最后:运行测试:

在这里插入图片描述

2. Bean的作用域不同,管理方式也将是不同的

Spring 根据 Bean 的作用域来选择管理方式。

  1. 对于 singleton (spring 默认的单例)作用域的 Bean ,Spring 能够精确地知道该 Bean 何时被创建,何时初始化完成的,以及何时被销毁的,符合上述的生命周期的“五步”,“七步”,“十步” 的流程。
  2. 而对于 prototype(多例) 作用域的 Bean,Spring 只负责创建,当容器创建了 Bean 的实例后,Bean 的实例就交给了客户端代码管理,Spring 容器将不再跟踪其生命周期。不符合上述的生命周期的“五步”,“七步”,“十步” 的流程。

如下:我们把上述的User类的“Bean 的生命周期“十步”演示法当中的 ”spring.xml文件中的配置scope设置为prototype。其他任何内容保持不变。进行演示

在这里插入图片描述

运行测试:

在这里插入图片描述

从运行结果上看:与之前的 bean 生命周期十步相比较看:我们可以明显的发现。Spring 仅仅到bean 创建后,就不再管理了。而是交给客户端进行自行管理了。spring 不再管理后面的操作了。

2.1 自己new的对象让Spring管理

有些时候可能会遇到这样的需求,某个java对象是我们自己new的,然后我们希望这个对象被Spring容器管理,怎么实现?

准备工作,我们首先创建一个 bean 对象,这里我们创建一个空的 Vip 类,作为 bean 。

在这里插入图片描述

我们需要通过 DefaultListableBeanFactory 这个对象,将我们 new 的对象交给 Spring 管理

再通过: DefaultListableBeanFactory 这个对象下的registerSingleton()方法,(这个交给 Spring 管理的bean的id/name 的命名,对于要交给spring管理的对象)
defaultListableBeanFactory.registerSingleton(“vipBean”,vip);

在这里插入图片描述

核心代码:

在这里插入图片描述

import com.rainbowsea.bean.User;
import com.rainbowsea.bean.Vip;
import org.junit.Test;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class BeanLifecycleTest {@Testpublic void test() {// 第一步: 我们自己 new 一个对象,方便交给 spring 管理Vip vip = new Vip();System.out.println(vip);  // 打印一下地址,方便比较//  第二步:将以上自己 new 的这个对象纳入 Spring 框架容器当中去管理,半路上交给 Spring来管理//  通过 DefaultListableBeanFactory 这个对象,将我们 new 的对象交给 Spring 管理DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();// 通过: registerSingleton()方法,(这个交给 Spring 管理的bean的id/name 的命名,对于要交给spring管理的对象)defaultListableBeanFactory.registerSingleton("vipBean",vip);// 从Spring 容器中获取:通过上述我们 registerSingleton()方法中定义的id,进行一个获取Object vipBean = defaultListableBeanFactory.getBean("vipBean");System.out.println(vipBean);// 单例:地址是一样的。}
}

我们是自己new 的对象,半路上交给 Spring 框架进行管理的,所以我们不需要配置spring.xml 的文件上配置相关的 bean 信息。

运行结果:

在这里插入图片描述

3. 总结:

  1. 熟悉Bean 的生命周期,各个时间节点上所能做的事情,可以让我们更加灵活的掌握Spring上的运用,更加的灵活,实现我们的业务需要。
  2. Bean 的生命周期 “五步”;注意点:初始化 Bean 需要我们通过在 spring.xml 配置文件当中的 标签当中通过 init-method= 属性指定初始化方法 是哪一个方法;销毁 Bean 也是需要我们通过在 spring.xml 配置文件当中的 标签当中的 destroy-method=性指定销毁方法 是哪个方法
  3. Bean 的生命周期分为“七步”;是在五步的当中的:第三步初始化Bean 的前后添加上的,Bean 的后处理器。如果加上 Bean 后处理器的话,Bean 的生命周期就是 七步了。该配置Bean后处理器。这个后处理器将作用于当前整个配置文件中所有的bean。
  4. Bean 的生命周期 “十步”;需要让类实现5个接口(BeanNameAware,BeanClassLoaderAware,BeanFactoryAware,InitializingBean,DisposableBean),并实现其中的所有方法:
  5. singleton (spring 默认的单例)作用域的 Bean ,Spring 能够精确地知道该 Bean 何时被创建,何时初始化完成的,以及何时被销毁的,符合上述的生命周期的“五步”,“七步”,“十步” 的流程。
  6. Bean的作用域不同,管理方式也将是不同的;而对于 prototype(多例) 作用域的 Bean,Spring 只负责创建,不符合上述的生命周期的“五步”,“七步”,“十步” 的流程。 singleton (spring 默认的单例)作用域的 Bean 符合上述的生命周期的“五步”,“七步”,“十步” 的流程。
  7. 自己new的对象让Spring管理(将以上自己 new 的这个对象纳入 Spring 框架容器当中去管理,半路上交给 Spring来管理);通过: DefaultListableBeanFactory 这个对象下的registerSingleton()方法,(这个交给 Spring 管理的bean的id/name 的命名,对于要交给spring管理的对象)

4. 最后:

“在这个最后的篇章中,我要表达我对每一位读者的感激之情。你们的关注和回复是我创作的动力源泉,我从你们身上吸取了无尽的灵感与勇气。我会将你们的鼓励留在心底,继续在其他的领域奋斗。感谢你们,我们总会在某个时刻再次相遇。”

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.tpcf.cn/diannao/5303.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Flask 3 保姆级教程(一):快速上手

一、创建项目 PyCharm 中新建项目 创建完成后会出现这么个项目 以下是代码解析&#xff1a; # 导入了 Flask 类 from flask import Flask# 创建了一个 Flask web 应用的实例&#xff0c;并将其赋值给变量 app # __name__ 是一个特殊的 Python 变量&#xff0c;它表示当前模块…

第49期|GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以找…

Unity Android(十) 适配Android14系统

开发环境&#xff1a;Unity2019.4 Android14平板 AndroidStudio2020.3.1 本文仅作个人记录&#xff0c;方便后续回顾。 请求权限 MANAGE_EXTERNAL_STORAGE 参考链接&#xff1a;https://blog.csdn.net/qq_34765850/article/details/136045431 将应用更新为以 Android …

变电站自动化控制系统应用案例分析

变电站自动化控制系统介绍 变电站自动化控制系统用于大中型企业变电站项目&#xff0c;这类企业变压器多&#xff0c;日耗电量大。把多个变压器集中到一个电器平台上&#xff0c;集中管理分析&#xff0c;优化厂区用电管理&#xff0c;从而达到集中控制、集中分析、集中管理的…

VOS系统录音文件REC转MP3,REC录音转WAV与WAV转MP3具体项目中实现方式,以及占用空间变化!

前面讲解了VOS3000系统的录音REC转MP3的安装步骤&#xff0c;不清楚的&#xff0c;可以移步这里查看&#xff1a;http://t.csdnimg.cn/OXNT9 或者 点击这里查看安装步骤&#xff0c;下面继续讲下他们的使用方法&#xff0c;以及实际项目中的运用&#xff0c;首先我们需要明确我…

Android中的屏幕刷新机制(动画视频形象说明机制)

一&#xff0c;刷新率和帧率&#xff0c;60hz和60fps的区别 在Android系统中&#xff0c;刷新率和帧率是两个不同的概念&#xff0c;它们各自在显示过程中扮演着不同的角色。以下是对它们的详细解释&#xff1a; 刷新率&#xff0c;单位是Hz&#xff0c;是指屏幕在一秒内刷新…

C++学习第九课:指针的精髓与应用

C学习第九课&#xff1a;指针的精髓与应用 1. 指针基础 指针是一种存储内存地址的变量&#xff0c;它指向另一个变量的内存位置。 int var 10; int *ptr &var; // ptr是指向var的指针2. 声明和初始化指针 声明指针时在类型前加星号(*)。 int *ptr; // 声明一个整型指…

STK与matlab交互 Astrogator模块(13)

一、背景介绍 在本文介绍一个场景&#xff0c;五颗蓝方卫星和一颗红方卫星&#xff0c;在两个小时之内&#xff0c;使用神经网络等人工智能算法&#xff0c;实现一个轨道追踪的问题&#xff0c;其中接口输入是六颗卫星在J2000坐标系下的坐标&#xff0c;接口输出是该六颗卫星沿…

使用ssh一台机器跳转到另一台机器

//默认端口是22. 1、ssh 用户名ipssh root192.168.111.3//如果端口不是22需要指定端口 2、ssh -p 端口号 用户名ip ssh -p 8888 root192.168.111.3

vue中@click.prevent函数的使用

一个困扰我很久的问题&#xff0c;后端使用djangoDRF框架开发api&#xff0c;前端使用vueaxioselement plus写的登录功能&#xff0c;后端已经设置了允许跨域&#xff0c;使用postman请求接口正常&#xff0c;但是使用浏览器登录时&#xff0c;后端返回[25/Apr/2024 18:13:13,1…

windows下安装onlyoffice

文章目录 1、 安装ErLang2、 安装rabbitmq3、 安装postgresql4、 安装onlyoffice(社区版) 1、 安装ErLang 下载地址&#xff1a;https://erlang.org/download/otp_win64_24.2.exe opt_wind64_24.2.exe 直接运行&#xff0c;一步一步安装 2、 安装rabbitmq 下载地址&#xf…

.NET C# ORM 瀚高数据库

SqlSugar ORM SqlSugar 是一款 老牌 .NET开源ORM框架&#xff0c;由果糖大数据科技团队维护和更新 &#xff0c;开箱即用最易上手的ORM 优点 &#xff1a;【生态丰富】【高性能】【超简单】 【功能全面】 【多库兼容】【适合产品】 【SqlSugar视频教程】 支持 &#xff1a…

linux部署java1.8(java17)

两种方式&#xff1a; 方式一 1.输入查找命令&#xff1a; yum -y list java*2.输入安装命令&#xff1a; yum install -y java-1.8.0-openjdk.x86_643.测试是否已经安装&#xff1a; java -version方式二&#xff1a; 点击链接进入官网&#xff1a;https://www.oracle.com/…

go设计模式之组合设计模式

组合设计模式 简介 将对象组合成树形结构以表示“部分-整体”的层次结构。组合设计模式使得用户对单个对象和组合对象的使用具有一致性。 参与者 Component 为组合中的对象声明接口 Leaf 在组合中表示叶子节点对象。 Composite 存储子部件。访问和管理子部件。 案例1 c…

H3C无线AP管理命令

先上链接 01-AP管理命令-新华三集团-H3C display wlan ap all

程序设计:C语言 调用命令行程序并获得输出 popen(源码)

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 这是个很基本的功能&#xff0…

记录不熟悉的函数用法(C++)——assign

1. assign (仅顺序容器) 记录起因&#xff1a;不知道一个vector给另一个vector在不是初始化时是如何赋值的&#xff0c;于是翻看《C Primer》&#xff0c;在“标准库类型vector”这一节中&#xff0c;并没有得到解答。于是&#xff0c;上网搜索&#xff0c;搜到一篇&#xff0…

redis安装配置

简单启动一个redis容器 拉取redis镜像&#xff1a;(更多版本看https://hub.docker.com/_/redis/tags) sudo docker pull redis:7.2.4简单启动一个redis服务 &#xff0c;–requirepass 指定密码 123456 sudo docker run -d \ --name redis \ --restartalways \ -p 6379:6379…

Java 如何避免代码中大量的 if else 判断

文章目录 Java 如何避免代码中大量的 if else 判断解决方案1.策略模式2.工厂模式3.策略模式 工厂模式4.提前 return&#xff08;适用于分支逻辑很简单的 if else&#xff09;5.枚举 Java 如何避免代码中大量的 if else 判断 在代码中经常会出现 if else 判断&#xff0c;如下…

当众演讲技巧的方法有哪些(3篇)

当众演讲技巧的方法有哪些&#xff08;3篇&#xff09; 当众演讲技巧的方法有很多&#xff0c;下面我将分三篇来详细阐述其中的一些关键技巧&#xff1a; **篇&#xff1a;准备与开场技巧 充分准备&#xff1a;提前规划演讲内容&#xff0c;明确主题和目标&#xff0c;准备详…