IOC中Bean的生命周期

news2024/11/15 13:44:25

生命周期的各个阶段:

可以分为三个阶段:产生-使用-销毁

又可以分四个阶段:四个阶段  实例化 ->属性注入->初始化 ->销毁

实例化后到使用的初始化过程: 属性赋值 ->处理各种Aware接口->实现BeanPostProcessor的before方法->nitializingBean接口的初始化方法回调->实现BeanPostProcessor的after方法

Bean实例化流程概述:

Spring 容器在进行初始化时,会将 xml 配置的的信息封装成一个  BeanDefinition  对象,所有的
BeanDefinition 存储到一个名为 beanDefinitionMap Map 集合中去, Spring 框架在对该 Map 进行遍 历,使用反射创建Bean 实例对象,创建好的 Bean 对象存储在一个名为 singletonObjects Map 集合 中,当调用getBean 方法时则最终从该 Map 集合中取出 Bean 实例对象返回

扫描配置信息:

        在启动之处,Spring会加载Bean定义 loadBeanDefinitions方法,用xml,注解扫描等各种方式,将定义的所有Bean全部找到,存放到一个BeanDifinitionMap中去。

实例化Bean:

         通过工厂后处理器的接口,实现对Bean的修改或注册

  ApplicaContext通过遍历BeanDifinitionMap来创建对象。

        我们可以在BeanDefinitionMap 填充完毕, Bean 实例化之前,通过实现接口 BeanFactoryPostProcessor:来对实例化的类进行修改或者注册。
        
        
        如下代码所示,我们自己创建类MyBeanFactoryPostPro 实现 BeanFactoryPostProcessor,并且重写了里面的postProcessBeanFactory方法,成功对BeanDifinitionMap中,Key为user,Value为User的map修改为,Key为user,value为Student,实现了对类的修改
public class MyBeanFactoryPostPro implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {


//                通过ConfigurableListableBeanFactory 的getBeanDefinition方法获取beanDefinition对象,修改beanClassname,完成实例化对象的修改
       
   BeanDefinition    beanDefinition     =               
   configurableListableBeanFactory.getBeanDefinition("user");
        beanDefinition.setBeanClassName("com.apersource.test.Student");

    }
}

同理,我们在如下代码中,通过是实现BeanDefinitionRegistryPostProcessor接口,并且重写了里面的方法,来注册了一个Bean到BeanDifinitionMap中去。

public class MyBeanFactoryPostProcessor2 implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {

        //进行注册
        RootBeanDefinition definition = new RootBeanDefinition();
        definition.setBeanClassName("com.apersource.test.Student");
        beanDefinitionRegistry.registerBeanDefinition("stu2",definition);
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {

    }
}

属性注入

通过populateBean方法为Bean内部所需的属性进行赋值填充,这些属性通常为@Autowired注解修饰的这些变量,Spring会通过三级缓存机制来进行属性填充,避免依赖闭环。

        我认为三级缓存的核心思想便是将实例化与属性赋值分开,将不完整的Bean先拿来使用,实现对依赖闭环的突破,再重新对每个Bean对象完成属性赋值(拙见)。

感知实现的Aware接口,并进行处理

 */
public class User implements BeanNameAware, InitializingBean {
    public String name;

    public User() {
        System.out.println("实例化~");
    }

    public void setName(String name) {
        System.out.println("属性赋值");
        this.name = name;
    }

    @Override
    public void setBeanName(String s) {
        System.out.println("各种aware接口的使用");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("来自接口系统的初始化方法");
    }

    public void doinit(){
        System.out.println("自定义属性的初始化方法");
    }
}

如上代码所演示举例,我们获得一个不完整的Bean之后,对他进行属性赋值,之后首先Spring要处理的就是Aware接口的各种方法,如上实现了 BeanNameAware 接口,我们在其中输出一段语句,获取Bean时便可以清楚的看到执行顺序;

BeanPostProcessor

然后我们开始处理BeanPostProcessor的before和after方法,顾名思义分别在初始化前和初始化之后

public class MyPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("初始化前的后处理器");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("初始化后的后处理器");
        return bean;
    }
}

初始化的方法:

BeanPostProcessor的before和after方法之间

我们通过实现 InitializingBean 接口,重写里面的 afterPropertiesSet方法,实现了来自接口的初始化方法,在这之后我们如果有自定义的初始化方法并且声明在了配置文件中,会在基于接口的初始化方法之后执行,。

到此为止,一个完整的Bean对象将创建完成了,创建好的Bean对象存储在一个名为singletonObjectsMap集合

然后就是使用和销毁了;

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

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

相关文章

【大厂AI课学习笔记NO.63】模型的维护

说是模型的维护,其实这堂课都是在讲“在工业环境中开发和部署机器学习模型的流程”。 上图来自于我的笔记思维脑图,已经上传,要链接的访问的主页查看资源。 一路走来,我们学习了数据管理、模型学习、模型验证、模型部署等重要的步…

js中Generator函数详解

定义: promise是为了解决回调地狱的难题出现的,那么 Generator 就是为了解决异步问题而出现的。 普通函数,如果调用它会立即执行完毕;Generator 函数,它可以暂停,不一定马上把函数体中的所有代码执行完毕…

鸿蒙App开发新思路:小程序转App

国家与国家之间错综复杂,在谷歌的安卓操作系统“断供”后,鸿蒙系统的市场化&独立化的道路便显而易见了。 2024年1月18日,华为宣布,不再兼容安卓的“纯血鸿蒙”--HarmonyOS NEXT鸿蒙星河版最终面世,并与2024年Q4正…

自己本地模拟内存数据库增删改查

目录 学习初衷准备代码实现结果感谢阅读 学习初衷 用于满足自己的测试要求,不连接数据库,也不在意数据丢失 准备 maven依赖 org.springframework.boot spring-boot-starter-test test 代码实现 内存数据库(InMemoryDatabase&#xff0…

AmzTrends x TiDB Serverless:通过云原生改造实现全局成本降低 80%

本文介绍了厦门笛卡尔数据(AmzTrends)在面临数据存储挑战时,选择将其数据分析服务迁移到 TiDB Serverless 的思路和实践。通过全托管的数据库服务,AmzTrends 实现了全局成本降低 80% 的效果,同时也充分展示了 TiDB Ser…

【活动】金三银四,前端工程师如何把握求职黄金期

随着春意盎然的气息弥漫大地,程序员群体中也迎来了一年一度的“金三银四”求职热潮。这个时间段对于广大前端工程师而言,不仅象征着生机勃发的新起点,更是他们职业生涯中至关重要的转折点。众多知名公司在这一时期大规模开启招聘通道&#xf…

Java面试题总结200道(二)

26、简述Spring中Bean的生命周期? 在原生的java环境中,一个新的对象的产生是我们用new()的方式产生出来的。在Spring的IOC容器中,将这一部分的工作帮我们完成了(Bean对象的管理)。既然是对象,就存在生命周期,也就是作用…

机器人持续学习基准LIBERO系列9——数据集轨迹查看

0.前置 机器人持续学习基准LIBERO系列1——基本介绍与安装测试机器人持续学习基准LIBERO系列2——路径与基准基本信息机器人持续学习基准LIBERO系列3——相机画面可视化及单步移动更新机器人持续学习基准LIBERO系列4——robosuite最基本demo机器人持续学习基准LIBERO系列5——…

windows下安装npm

windows下安装了多个node.js如何切换npm。 下载nvm 下载nvm地址:https://github.com/coreybutler/nvm-windows/releases 安装nvm 这个是nodejs的安装位置,如果没有nodejs文件夹就新建一个(后来发现他会自动生成一个快捷方式) 设置setting.txt 打开安装…

http 协议深入介绍

一,http 相关概念 (一)关键名词 1,互联网 是网络的网络,是所有类型网络的母集 2,因特网 世界上最大的互联网网络。即因特网概念从属于互联网概念。习惯上,大家把连接在因特网上的计算机都成…

【大厂AI课学习笔记NO.66】TensorFlow

TensorFlow 这个框架,实在是太有名了,最近周红衣都在大力的宣传和讲解。 他说的是对的,人工智能,就是大力出奇迹,就是大量的算力,大量的数据,加上模型的加持,实现的智能感觉。 Goog…

MWC 2024丨Smart Health搭载高通Aware平台—美格发布智能健康看护解决方案,开启健康管理新体验

2月29日,在MWC 2024世界移动通信大会上,全球领先的无线通信模组及解决方案提供商——美格智能正式发布了新一代Cat.1模组SLM336Q,是中低速物联网应用场景的高性价比之选。本次还发布了首款搭载高通Aware™平台的智能看护解决方案MC303&#x…

MATLAB知识点:for-end语句(简称for循环)

​讲解视频:可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。​ MATLAB教程新手入门篇(数学建模清风主讲,适合零基础同学观看)_哔哩哔哩_bilibili 节选自​第4章:MATLAB程序流程控制 for-end语句&…

探索Hadoop的三种运行模式:单机模式、伪分布式模式和完全分布式模式

目录 前言一、 单机模式二、 伪分布式模式三、 完全分布式模式(重点)3.1 准备工作3.2 配置集群3.2.1 配置core-site.xml 文件3.2.2 配置hdfs-site.xml 文件3.2.3 配置yarn-site.xml 文件3.2.4 配置mapred-site.xml 文件 3.3 启动集群3.3.1 配置workers3.…

HTML+CSS:花式加载

效果演示 实现了一个动态加载文本效果&#xff0c;通过定义变量和应用动画效果来实现文本的动态展示。 Code <div class"container"><h1>loading...</h1> </div>:root {--text-color: orangered; /* 定义文本颜色变量为橙红色 */--inner-st…

[设计模式Java实现附plantuml源码~行为型]定义算法的框架——模板方法模式

前言&#xff1a; 为什么之前写过Golang 版的设计模式&#xff0c;还在重新写Java 版&#xff1f; 答&#xff1a;因为对于我而言&#xff0c;当然也希望对正在学习的大伙有帮助。Java作为一门纯面向对象的语言&#xff0c;更适合用于学习设计模式。 为什么类图要附上uml 因为很…

RedisTemplate的坑人之处

使用long类型的值存入redis,用int类型无法取出 原因是因为代码中的key传递到内部进行序列化&#xff0c;不同类型的值序列化的结果不一样&#xff0c;就导致最终实际存入redis的key不一样 比如&#xff1a; int x1 假设序列化后是 1(int、Integer) long y1 就是 1(long,Long) …

吴恩达deeplearning.ai:学习曲线决定下一步怎么做

以下内容有任何不理解可以翻看我之前的博客哦&#xff1a;吴恩达deeplearning.ai专栏 学习曲线是一种图形表示方法&#xff0c;用于展示模型在训练过程中的学习表现&#xff0c;即模型的训练集和验证集上的性能如何随着训练时间的增加而变化。可以帮助我们了解模型的学习进度。…

【大厂AI课学习笔记NO.65】机器学习框架和深度学习框架

笔记思维脑图已上传&#xff0c;访问我的主页可下载。 https://download.csdn.net/download/giszz/88868909 广义上&#xff0c;机器学习框架包含了深度学习框架。 本质上&#xff0c;机器学习框架涵盖分类、回归、聚类、异常检测和数据准备等各种学习方法。 深度学习框架涵…

足球青训俱乐部|基于Springboot的足球青训俱乐部管理系统设计与实现(源码+数据库+文档)

足球青训俱乐部管理系统目录 目录 基于Springboot的足球青训俱乐部管理系统设计与实现 一、前言 二、系统设计 1、系统架构设计 三、系统功能设计 1、管理员登录界面 2、公告信息管理界面 3、学员管理界面 4、商品信息管理界面 5、课程安排管理界面 四、数据库设计…