SpringBoot之LazyInitializationBeanFactoryPostProcessor类源码学习

news2025/1/14 23:40:34

源码分析

/**
 *
 * @author Andy Wilkinson
 * @author Madhura Bhave
 * @author Tyler Van Gorder
 * @author Phillip Webb
 * @since 2.2.0
 * @see LazyInitializationExcludeFilter
 *
 * 主要用于延迟初始化 Bean 的配置。它通过修改 BeanFactory 的配置来确保某些 Bean 在实际需要时才进行初始化,而不是在应用启动时就全部初始化。这有助于提高应用的启动速度和资源利用率。
 */
public final class LazyInitializationBeanFactoryPostProcessor implements BeanFactoryPostProcessor, Ordered {

	/**
	 * 在BeanFactory初始化后对bean进行后处理
	 * 主要用于处理延迟初始化相关的逻辑
	 *
	 * @param beanFactory ConfigurableListableBeanFactory类型的参数,代表BeanFactory
	 * @throws BeansException 如果处理过程中遇到错误,则抛出此异常
	 */
	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		// Take care not to force the eager init of factory beans when getting filters
		//获取LazyInitializationExcludeFilter类型的bean
		Collection<LazyInitializationExcludeFilter> filters = beanFactory
				.getBeansOfType(LazyInitializationExcludeFilter.class, false, false).values();
		//遍历容器中的所有bean定义
		for (String beanName : beanFactory.getBeanDefinitionNames()) {
			//根据beanName获取bean的定义
			BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
			//检查bean定义是否为AbstractBeanDefinition类型
			if (beanDefinition instanceof AbstractBeanDefinition) {
				//如果是,则进行延迟初始化处理
				postProcess(beanFactory, filters, beanName, (AbstractBeanDefinition) beanDefinition);
			}
		}
	}


	/**
	 * 根据条件更新bean的懒初始化状态
	 *
	 * @param beanFactory Bean工厂,用于获取bean的相关信息
	 * @param filters 排除懒初始化的过滤器集合
	 * @param beanName 当前bean的名称
	 * @param beanDefinition 当前bean的定义,包含懒初始化状态
	 */
	private void postProcess(ConfigurableListableBeanFactory beanFactory,
							 Collection<LazyInitializationExcludeFilter> filters, String beanName,
							 AbstractBeanDefinition beanDefinition) {
		// 如果bean的懒初始化状态已明确,无需处理
		Boolean lazyInit = beanDefinition.getLazyInit();
		if (lazyInit != null) {
			return;
		}
		// 获取bean的类型
		Class<?> beanType = getBeanType(beanFactory, beanName);
		//如果该bean不再filters列表中,则LazyInit设置为true
		if (!isExcluded(filters, beanName, beanDefinition, beanType)) {
			//给这个bean设置延迟初始化
			beanDefinition.setLazyInit(true);
		}
	}


	private Class<?> getBeanType(ConfigurableListableBeanFactory beanFactory, String beanName) {
		try {
			return beanFactory.getType(beanName, false);
		}
		catch (NoSuchBeanDefinitionException ex) {
			return null;
		}
	}


	/**
	 * 判断指定的bean是否被排除在懒初始化之外
	 *
	 * @param filters 一个包含多个排除过滤器的集合,用于判断bean是否应该被排除
	 * @param beanName bean的名称,用于在过滤时进行标识
	 * @param beanDefinition bean的定义信息,包含了bean的元数据
	 * @param beanType bean的类型,可能为null,用于类型级别的过滤
	 * @return 如果bean被至少一个过滤器认定为需要排除,则返回true;否则返回false
	 */
	private boolean isExcluded(Collection<LazyInitializationExcludeFilter> filters, String beanName,
							   AbstractBeanDefinition beanDefinition, Class<?> beanType) {
		// 如果bean类型不为null,遍历所有过滤器以判断bean是否应被排除
		if (beanType != null) {
			for (LazyInitializationExcludeFilter filter : filters) {
				// 如果当前过滤器认为bean应被排除,则直接返回true
				if (filter.isExcluded(beanName, beanDefinition, beanType)) {
					return true;
				}
			}
		}
		// 如果没有过滤器认为bean应被排除,则返回false
		return false;
	}


	@Override
	public int getOrder() {
		return Ordered.HIGHEST_PRECEDENCE;
	}

}

测试案例

class LazyInitializationExcludeFilterTests {

	@Test
	void forBeanTypesMatchesTypes() {
		// 创建一个LazyInitializationExcludeFilter,排除CharSequence和Number类型的bean
		LazyInitializationExcludeFilter filter = LazyInitializationExcludeFilter.forBeanTypes(CharSequence.class,
				Number.class);

		// 定义一个测试用的bean名称
		String beanName = "test";

		// 模拟一个BeanDefinition对象
		BeanDefinition beanDefinition = mock(BeanDefinition.class);

		// 验证filter是否正确排除了CharSequence类型
		System.out.println("验证filter是否正确排除了CharSequence类型:"+filter.isExcluded(beanName, beanDefinition, CharSequence.class));

		// 验证filter是否正确排除了String类型(CharSequence的子类型)
		System.out.println("验证filter是否正确排除了String类型(CharSequence的子类型):"+filter.isExcluded(beanName, beanDefinition, String.class));

		// 验证filter是否正确排除了StringBuilder类型(CharSequence的子类型)
		System.out.println("验证filter是否正确排除了StringBuilder类型(CharSequence的子类型):"+filter.isExcluded(beanName, beanDefinition, StringBuilder.class));

		// 验证filter是否正确排除了Number类型
		System.out.println("验证filter是否正确排除了Number类型:"+filter.isExcluded(beanName, beanDefinition, Number.class));

		// 验证filter是否正确排除了Long类型(Number的子类型)
		System.out.println("验证filter是否正确排除了Long类型(Number的子类型):"+filter.isExcluded(beanName, beanDefinition, Long.class));

		// 验证filter是否正确不排除Boolean类型(非Number类型)
		System.out.println("验证filter是否正确不排除Boolean类型(非Number类型):"+filter.isExcluded(beanName, beanDefinition, Boolean.class));
	}


}

测试结果

验证filter是否正确排除了CharSequence类型:true
验证filter是否正确排除了String类型(CharSequence的子类型):true
验证filter是否正确排除了StringBuilder类型(CharSequence的子类型):true
验证filter是否正确排除了Number类型:true
验证filter是否正确排除了Long类型(Number的子类型):true
验证filter是否正确不排除Boolean类型(非Number类型):false

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

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

相关文章

Spring Boot 2 学习全攻略

Spring Boot 2 学习资料 Spring Boot 2 学习资料 Spring Boot 2 学习资料 在当今快速发展的 Java 后端开发领域&#xff0c;Spring Boot 2 已然成为一股不可忽视的强大力量。它简化了 Spring 应用的初始搭建以及开发过程&#xff0c;让开发者能够更加专注于业务逻辑的实现&am…

31_搭建Redis分片集群

Redis的主从复制模式和哨兵模式可以解决高可用、高并发读的问题。但是依然有两个问题没有解决:海量数据存储问题、高并发写的问题。由于数据量过大,单个master复制集难以承担,因此需要对多个复制集进行集群,形成水平扩展每个复制集只负责存储整个数据集的一部分,这就是Red…

IMX6U Qt 开发环境

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言 一、交叉编译 1. 安装通用 ARM 交叉编译工具链 2. 安装 Poky 交叉编译工具链 二、编译出厂源码 1. U-boot 2. 内核和模块 3. 编译出厂 Qt GUI 综合 Demo 前言…

数据结构与算法之链表: LeetCode 92. 反转链表 II (Ts版)

反转链表 II https://leetcode.cn/problems/reverse-linked-list-ii/description/ 描述 给你单链表的头指针 head 和两个整数 left 和 right &#xff0c;其中 left < right请你反转从位置 left 到位置 right 的链表节点&#xff0c;返回 反转后的链表 示例 1 输入&…

【Uniapp-Vue3】@import导入css样式及scss变量用法与static目录

一、import导入css样式 在项目文件中创建一个common文件夹&#xff0c;下面创建一个css文件夹&#xff0c;里面放上style.css文件&#xff0c;编写的是公共样式&#xff0c;我们现在要在App.vue中引入该样式。 在App.vue中引入该样式&#xff0c;这样就会使样式全局生效&#…

MySQL中的四种表联结

目录 1、联结、关系表 &#xff08;1&#xff09;关系表 &#xff08;2&#xff09;为什么使用联结 2、如何创建联结 &#xff08;1&#xff09;笛卡尔积&#xff08;叉联结&#xff09;--用逗号分隔 &#xff08;2&#xff09;where子句的重要性 &#xff08;3&#xff…

DVWA靶场CSRF漏洞通关教程及源码审计

目录标题 CSRFlow源码审计 medium源码审计 high源码审计 impossible源码审计 CSRF low 先修改密码 看到地址栏 复制在另一个网页打开 成功登录 源码审计 没有任何过滤措施&#xff0c;很危险&#xff0c;并且采用了不安全的md5加密 <?phpif( isset( $_GET[ Change ] )…

JVM之垃圾回收器G1概述的详细解析

G1(并发) G1 特点 G1&#xff08;Garbage-First&#xff09;是一款面向服务端应用的垃圾收集器&#xff0c;应用于新生代和老年代、采用标记-整理算法、软实时、低延迟、可设定目标&#xff08;最大 STW 停顿时间&#xff09;的垃圾回收器&#xff0c;用于代替 CMS&#xff0…

宝塔面板 申请证书后 仍然提示不安全

证书显示有效&#xff0c;但是网站显示不安全 导致的原因是引入静态文件使用的是HTTP&#xff0c;查看方法为F12打开console控制台 可以看到静态文件全部都是HTTP 网站采用wordpress搭建&#xff0c;基于问题解决&#xff0c;其他方式搭建也是一样&#xff0c;处理掉所有的H…

【1】Word:邀请函

目录 题目 文字解析 流程 题目 文字解析 考生文件夹☞Word.docx☞一定要用ms打开&#xff0c;wps打开作答无效☞作答完毕&#xff0c;F12或者手动另存为&#xff08;考生文件夹&#xff1a;路径文件名&#xff09; 注意&#xff1a;一定要检查&#xff0c;很有可能你前面步…

Docker安装和卸载(centos)

Docker安装和卸载 一&#xff0c;已安装Docker&#xff0c;卸载Docker 1.方法一 sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine​ 如果出现以下提示就证明没卸载…

JVM:ZGC详解(染色指针,内存管理,算法流程,分代ZGC)

1&#xff0c;ZGC&#xff08;JDK21之前&#xff09; ZGC 的核心是一个并发垃圾收集器&#xff0c;所有繁重的工作都在Java 线程继续执行的同时完成。这极大地降低了垃圾收集对应用程序响应时间的影响。 ZGC为了支持太字节&#xff08;TB&#xff09;级内存&#xff0c;设计了基…

ASP.NET Core - 日志记录系统(二)

ASP.NET Core - 日志记录系统&#xff08;二&#xff09; 2.4 日志提供程序2.4.1 内置日志提供程序2.4.2 源码解析 本篇接着上一篇 ASP.NET Core - 日志记录系统(一) 往下讲&#xff0c;所以目录不是从 1 开始的。 2.4 日志提供程序 2.4.1 内置日志提供程序 ASP.NET Core 包括…

无源器件-电容

电容器件的参数 基本概念由中学大学物理或电路分析内容获得&#xff0c;此处不做过多分析。 电容的产量占全球电子元器件产品的40%以上。 单位&#xff1a;法拉 F&#xff1b;1F10^6uF&#xff1b;电路中常见的104电容就是10*10^4pF100nF0.1uF C为电容&#xff0c;Rp为绝缘电…

云平台一键部署【Video-Background-Removal】视频换背景,无任何限制,随意换

Video-Background-Removal 是一款革命性的视频背景替换工具&#xff0c;旨在让用户轻松实现视频背景的快速更换。无论你是专业创作者还是普通用户&#xff0c;这款软件都能让你在几秒钟内改变背景&#xff0c;完全消除限制&#xff0c;随心所欲&#xff0c;随时随地想换就换&am…

HCIP笔记1--IP路由基础回顾、BFD单臂回声、OSPF基础

1. 路由基础回顾 概念 AS(Aotonomous System): 自治系统&#xff0c;由同一机构管理的路由器集合。LAN(Local Area Network): 局域网&#xff0c;用户所使用的网络WAN(Wideless Area Network): 广域网&#xff0c;运营商网络广播域&#xff1a;一个广播帧能在网络中到达的所有…

【Linux网络编程】数据链路层 | MAC帧 | ARP协议

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站 &#x1f308;个人主页&#xff1a; 南桥几晴秋 &#x1f308;C专栏&#xff1a; 南桥谈C &#x1f308;C语言专栏&#xff1a; C语言学习系…

微软与腾讯技术交锋,TRELLIS引领3D生成领域多格式支持新方向

去年 11 月&#xff0c;腾讯推出 Hunyuan3D 生成模型&#xff0c;是业界首个同时支持文字和图像生成 3D 的开源大模型。紧接着不到一个月&#xff0c;微软便发布了全新框架 TRELLIS&#xff0c;加入 3D 资产生成领域的竞争中。TRELLIS 支持多格式输出&#xff0c;包括辐射场、3…

【爬虫】单个网站链接爬取文献数据:标题、摘要、作者等信息

源码链接&#xff1a; https://github.com/Niceeggplant/Single—Site-Crawler.git 一、项目概述 从指定网页中提取文章关键信息的工具。通过输入文章的 URL&#xff0c;程序将自动抓取网页内容 二、技术选型与原理 requests 库&#xff1a;这是 Python 中用于发送 HTTP 请求…

设计模式-结构型-组合模式

1. 什么是组合模式&#xff1f; 组合模式&#xff08;Composite Pattern&#xff09; 是一种结构型设计模式&#xff0c;它允许将对象组合成树形结构来表示“部分-整体”的层次结构。组合模式使得客户端对单个对象和组合对象的使用具有一致性。换句话说&#xff0c;组合模式允…