spring-core-9-92 | Spring Bean Class加载阶段:BD对应的Class是怎样加载的?

本文深入探讨Spring Bean在创建前的Class加载过程,涉及ClassLoader、Java Security、ConfigurableBeanFactory的角色。文章通过代码示例,详细解释了BeanDefinition如何从文本元信息转化为实际的Class,以及在加载过程中如何处理安全控制和临时ClassLoader。最后,总结了BeanDefinition的Class加载关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring Bean Class 加载阶段

上一节分析了关于 BeanDefinition 合并的细节过程, 那么接下来在 Spring Bean 被创建之前, 需要将Bean对应的class进行加载. 那么这里就要涉及到一些细节需要理清.

ClassLoader 类加载

第一个涉及到 java 里面的一些基础, ClassLoader , 这个东西其实接触框架的同学会更加熟悉, java的类加载主要是依靠 ClassLoader 来进行的.

可以参考:
java ClassLoader详解

Java Security 安全控制

第二个是关于java security,就是Java安全里面的一些控制,在spring早期是没有增加这块的实现的,后期开始增加了一些相关的控制,多提一点,过去是spring在实现的时候,在 IoC 的实现DI和我们说依赖注入和依赖查找的时候,他没有注重关于Java Security的一个安全整合,不过在这方面 Java EE 规范里面有清晰的描述,所以后续在当前版本看的时候,会发现里面有一些 Java Security API 的代码,后面会讲到这些代码的作用.

ConfigurableBeanFactory 临时ClassLoader

第三个方面,这个方面是个大的方面,这个方面本节其实选择性的跳过,后面会带入一个简单的场景和大家分析一下,这个场景实际上是非常有限的,通常我们是用不到的。

代码示例

java.lang.ClassLoader
org.springframework.beans.factory.config.BeanDefinition
org.springframework.beans.factory.support.AbstractBeanFactory
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
org.springframework.util.ClassUtils
java.lang.Class

org.geekbang.thinking.in.spring.bean.lifecycle.MergedBeanDefinitionDemo

从问题开始, BeanDefinition 是怎么 从文本的元信息形式加载到 Class 的?

好,我们还是回到idea里面来,前面章节知道了 BeanDefinition 在合并之后会生成 RootBeanDefinition。那么接下来有很重要的一个操作,就是我们前面看到过 BeanDefinition 实际上里面有一个很重要的信息,这个是我们的bean的一个基本的来源,也就是说它会 getBeanClassName

org.springframework.beans.factory.config.BeanDefinition#getBeanClassName

	/**
	 * Return the current bean class name of this bean definition.
	 * <p>Note that this does not have to be the actual class name used at runtime, in
	 * case of a child definition overriding/inheriting the class name from its parent.
	 * Also, this may just be the class that a factory method is called on, or it may
	 * even be empty in case of a factory bean reference that a method is called on.
	 * Hence, do <i>not</i> consider this to be the definitive bean type at runtime but
	 * rather only use it for parsing purposes at the individual bean definition level.
	 * @see #getParentName()
	 * @see #getFactoryBeanName()
	 * @see #getFactoryMethodName()
	 */
	@Nullable
	String getBeanClassName();

前面我们也分析过,其实 BeanDefinition 它是一个关于Bean的元信息的配置或者是描述,那么事实上它是通过文本的方式来进行呈现的,它这里并没有显式的告诉你它的类是什么,我们知道Java里面类的描述是通过Class来进行表达,那么Class又是由 ClassLoader 来进行加载的,因此这个BeanDefinition 实例化这一过程和我们的传统的Java的作用机制肯定是跑不掉的。

java.lang.ClassLoader

/**
 * A class loader is an object that is responsible for loading classes. The
 * class <tt>ClassLoader</tt> is an abstract class.  Given the <a
 * href="#name">binary name</a> of a class, a class loader should attempt to
 * locate or generate data that constitutes a definition for the class.  A
 * typical strategy is to transform the name into a file name and then read a
 * "class file" of that name from a file system.
 *
 */
public abstract class ClassLoader {
   

事实上在 Spring IoC容器的实现里面,ClassLoader 加载是一个边缘化的操作(其实是封装的太深了…),通常我们不太重视,接下来我们会通过一个方法的方式来进行操作。

首先我们看回之前的示例 MergedBeanDefinitionDemo,然后在依赖查找的位置打上断点:

org.geekbang.thinking.in.spring.bean.lifecycle.MergedBeanDefinitionDemo
org.geekbang.thinking.in.spring.bean.lifecycle.MergedBeanDefinitionDemo
org.springframework.beans.factory.support.AbstractBeanFactory#getMergedBeanDefinition(java.lang.String, org.springframework.beans.factory.config.BeanDefinition, org.springframework.beans.factory.config.BeanDefinition)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值