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.mzph.cn/diannao/5303.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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;您可以找…

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

变电站自动化控制系统介绍 变电站自动化控制系统用于大中型企业变电站项目&#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;是指屏幕在一秒内刷新…

STK与matlab交互 Astrogator模块(13)

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

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/…

H3C无线AP管理命令

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

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;准备详…

【蓝桥杯C++A组省三 | 一场勇敢的征途与致19岁的信】

随着4.13西大四楼考场的倒计时结束… 就这样蓝桥杯落幕了 省三的名次既满足又不甘心&#xff0c;但又确乎说得上是19岁途中的又一枚勋章 从去年得知&#xff0c;纠结是否要报名、到寒假开始战战兢兢地准备、陆续开始创作博客&#xff0c;记录好题和成长……感谢你们的关注&…

APT预警攻击平台截获Nday

APT预警攻击平台截获Nday 2024年4月26日 设备漏洞【漏洞利用】H3C Magic R100任意代码执行漏洞(CVE-2022-34598) 0000 &#xff1a; 0010 &#xff1a; 0020 &#xff1a; 0030 &#xff1a; 0040 &#xff1a; 0050 &#xff1a; 0060 &#xff1a; 0070 &#xff1a;6F 72…

请求接口报错:java.lang.IllegalStateException: argument type mismatch

目录 一、场景二、报错信息三、控制器四、接口调用五、原因六、解决 一、场景 1、调用后端接口报错 2、接口参数以Json方式传递 – 二、报错信息 java.lang.IllegalStateException: argument type mismatch Controller [com.xxx.huarunshouzheng.controller.MallControlle…

CCF-CSP真题题解:201409-3 字符串匹配

201409-3 字符串匹配 #include <iostream> #include <cstring> #include <algorithm> using namespace std;int n, type; string s, p;string tolower(string s) {string res;for (char c : s) res tolower(c);return res; }int main() {cin >> p >…

【探索Linux】P.33(HTTP协议)

阅读导航 引言一、认识URL二、URL编码和解码1. Urlencode&#xff08;URL编码&#xff09;2. Urldecode&#xff08;URL解码&#xff09; 三、HTTP的方法四、HTTP的状态码五、HTTP常见Header六、最简单的HTTP服务器温馨提示 引言 在上一篇文章中&#xff0c;我们深入探讨了“自…

LLaMA3(Meta)微调SFT实战Meta-Llama-3-8B-Instruct

LlaMA3-SFT LlaMA3-SFT, Meta-Llama-3-8B/Meta-Llama-3-8B-Instruct微调(transformers)/LORA(peft)/推理 项目地址 https://github.com/yongzhuo/LLaMA3-SFT默认数据类型为bfloat6 备注 1. 非常重要: weights要用bfloat16/fp32/tf32(第二版大模型基本共识), 不要用fp16, f…

坚守食品安全,美乐家(中国)守护大众健康

在现代社会&#xff0c;食品安全已成为公众关注的焦点&#xff0c;对于食品行业的企业而言&#xff0c;确保食品安全是极为重要的责任。产品是消费者与企业之间最直接、最紧密的纽带&#xff0c;也是消费者对品牌的最直观印象。因此&#xff0c;美乐家一直将产品质量、安全、绿…