IOC中Bean的生命周期

生命周期的各个阶段:

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

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

实例化后到使用的初始化过程: 属性赋值 ->处理各种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集合

然后就是使用和销毁了;

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据结构/C++:二叉搜索树

数据结构/C:二叉搜索树 概念模拟实现结构分析插入中序遍历查找删除析构函数拷贝构造赋值重载递归查找递归插入递归删除 总代码展示 概念 二叉搜索树(BST - Binary Search Tree)是一种特殊的二叉树,每个顶点最多可以有两个子节点。…

逆向案例四:360k静态和精灵数据动态AES解密,用js的方法

一、360K 网页链接:https://www.36kr.com/p/2672600261670407 页面中有静态的需要解密的内容,确定html包,确定方法 1.1方法步骤 在下方的搜索中输入decrypt(或者关键字window.initialState ,进入js文件 在AES.decrypt处打上断点&#xff0…

【Java项目介绍和界面搭建】拼图小游戏——键盘、鼠标事件

🍬 博主介绍👨‍🎓 博主介绍:大家好,我是 hacker-routing ,很高兴认识大家~ ✨主攻领域:【渗透领域】【应急响应】 【Java】 【VulnHub靶场复现】【面试分析】 🎉点赞➕评论➕收藏 …

15-Linux部署HBase集群

Linux部署HBase集群 简介 HBase 是一种分布式、可扩展、支持海量数据存储的 NoSQL 数据库。 和Redis一样,HBase是一款KeyValue型存储的数据库。 不过和Redis设计方向不同 Redis设计为少量数据,超快检索HBase设计为海量数据,快速检索 HB…

运行Python文件时出现‘utf-8’code can‘t decode byte 如何解决?(如图)

如图 亦或者出现“SyntaxError: Non-UTF-8 code starting with \xbb ” 出现这种问题往往是编码格式导致的,我们可以在py文件中的第一行加入以下代码: # codingutf-8或者 # codinggdk优先使用gbk编码 解释一下常用的两种编码格式: utf-…

供应链管理(SCM):界面设计全面扫盲,得供应链者得天下

大家伙,我是大千UI工场,专注UI分享和项目接单,本期带来供应链系统的设计分享,欢迎大家关注、互动交流。 一、什么是SCM SCM系统是供应链管理(Supply Chain Management)系统的缩写。供应链管理是指协调和管…

CSS列表属性

CSS列表属性 列表相关的属性&#xff0c;可以作用在 ul、ol、li 元素上。 代码如下&#xff1a; <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><title>列表相关属性</title><style>ul {/* …

MySQL的一行数据是如何存储的?

目录 1.COMPACT 行格式长什么样&#xff1f; 例子1&#xff1a;用户设置了主键值&#xff0c;列都是not null的。(默认字符集是utf8mb4,在这种情况下&#xff0c;char(N)类型就不是定长的了&#xff09; 例子2&#xff1a;没有设置主键&#xff0c;也没有唯一索引&#xff0…

微信小程序-生命周期

页面生命周期 onLoad: 页面加载时触发的方法&#xff0c;在这个方法中可以进行页面初始化的操作&#xff0c;如获取数据、设置页面状态等。 onShow: 页面显示时触发的方法&#xff0c;在用户进入页面或从其他页面返回该页面时会调用此方法。可以在此方法中进行页面数据刷新、动…

浅谈马尔科夫链蒙特卡罗方法(MCMC)算法的理解

1.解决的问题 计算机怎么在任意给定的概率分布P上采样&#xff1f;首先可以想到把它拆成两步&#xff1a; &#xff08;1&#xff09;首先等概率的从采样区间里取一个待定样本x&#xff0c;并得到它的概率为p(x) &#xff08;2&#xff09;然后在均匀分布U[0,1]上取一个值&a…

基于主从模式的Reactor的仿muduo网络库

&#x1f307;个人主页&#xff1a;平凡的小苏 &#x1f4da;学习格言&#xff1a;命运给你一个低的起点&#xff0c;是想看你精彩的翻盘&#xff0c;而不是让你自甘堕落&#xff0c;脚下的路虽然难走&#xff0c;但我还能走&#xff0c;比起向阳而生&#xff0c;我更想尝试逆风…

分布式系统中常用的缓存方案

1. 引言 随着互联网应用的发展和规模的不断扩大&#xff0c;分布式系统中的缓存成为了提升性能和扩展性的重要手段之一。本文将介绍几种在分布式系统中常用的缓存方案&#xff0c;包括分布式内存缓存、分布式键值存储、分布式对象存储和缓存网关等。 1.1 缓存在分布式系统中的…

数据结构c版(3)——排序算法

本章我们来学习一下数据结构的排序算法&#xff01; 目录 1.排序的概念及其运用 1.1排序的概念 1.2 常见的排序算法 2.常见排序算法的实现 2.1 插入排序 2.1.1基本思想&#xff1a; 2.1.2直接插入排序&#xff1a; 2.1.3 希尔排序( 缩小增量排序 ) 2.2 选择排序 2.2…

WPS如何共享文件和文件夹

1 WPS共享单个文件 用WPS打开要分享的文件&#xff0c;点击右上角的“分享”键&#xff0c;选择上传到云端。 之后点击“创建并分享”&#xff0c;即可分享该文档。 2 WPS创建共享文件夹 2.1 如何共享文件夹 首先打开WPS&#xff0c;点击左上角的首页。在首页栏中&#…

Sqli-labs靶场第21、22关详解[Sqli-labs-less-21、22]自动化注入-SQLmap工具注入|sqlmap跑base64加密

Sqli-labs-Less-21、22 由于21/22雷同&#xff0c;都是需要登录后&#xff0c;注入点通过Cookie值进行测试&#xff0c;值base64加密 修改注入数据 选项&#xff1a;--tamperbase64encode #自动化注入-SQLmap工具注入 SQLmap用户手册&#xff1a;文档介绍 - sqlmap 用户手册 由…

SpringBoot+mybatisplus运行单元测试类报错unable to find a @SpringBootConfiguration

这个问题一般是因为启动类目录和测试类不一致&#xff0c;或者没有写使用SpringBootApplication注解的启动类。 1.如果没写启动类&#xff0c;请在与测试类同目录层级&#xff08;注意是在main/java下对应的目录&#xff0c;即测试类在test/java下的目录为com.xxx则启动类需要…

代码随想录第45天|● 198.打家劫舍 ● 213.打家劫舍II ● 337.打家劫舍III

文章目录 ● 198.打家劫舍思路代码1.dp数组两个变量 ● 213.打家劫舍II思路&#xff1a;代码 ● 337.打家劫舍III思路代码&#xff1a; ● 198.打家劫舍 思路 代码 1.dp数组 class Solution {public int rob(int[] nums) {if(nums.length1)return nums[0];int[] dpnew int[nu…

6、JavaWeb-Mybatis

P116 Mybatis-入门 Mybatis是一款优秀的持久层框架&#xff0c;用于简化JDBC的开发。 持久层就是三层控制中的Dao层&#xff0c;数据访问层/持久层&#xff0c; P117 Mybatis-入门-快速入门程序 步骤&#xff1a; 创建springboot工程&#xff0c;数据表和实体类 引入mybat…

Centos7使用man查找命令时,报错No manual entry for xxxx

Centos7使用man查找命令时&#xff0c;报错No manual entry for xxxx 在Linux中使用man指令查找指令信息时&#xff0c;报No manual entry for xxxx。 比如使用man指令查找sleep3号手册时&#xff0c;出现以下错误&#xff1a; 这是由于没有安装man-pages这个rpm包导致的&#…

3、Linux-命令提示符与常用命令(一)

目录 一、命令提示符 二、命令格式 三、常用命令&#xff08;一&#xff09; 0、clear&#xff1a;清空终端窗口的内容。 1、ls&#xff1a;列出当前目录或指定目录下的文件和子目录 2、pwd&#xff1a;显示当前所在工作目录的完整路径。 3、cd&#xff1a;切换目录。 …