文章摘要(AI生成)
内部类实现流程测试用例我们测试用例如下:public class A { @Setter private String c; @Setter private B b; @NoArgsConstructor class B { @Setter
内部类实现流程
测试用例
我们测试用例如下:
public class A {
@Setter
private String c;
@Setter
private B b;
@NoArgsConstructor
class B {
@Setter
private String s;
}
}
spring配置如下:
<?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 id="a" class="org.jdbc.demo.A" >
<property name="c" value="1232"/>
<property name="b">
<bean class="org.jdbc.demo.A.B">
<constructor-arg ref="a"/>
<property name="s" value="hello"/>
</bean>
</property>
</bean>
</beans>
内部实现过程
首先我们debug,发现bean定义中的属性b会嵌套一层bean定义,结构如下:
在属性赋值时,我们会判断如果属性类型为BeanDefinitionHolder
或者BeanDefinition
,就执行内部bean的处理逻辑,本质上又再次调用对应的getBean()
方法处理内部bean对应的依赖bean对象和内部bean对象。
对应的内部bean处理代码为:
@Nullable
public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
//省略代码--其他类型的属性赋值
else if (value instanceof BeanDefinitionHolder) {
// Resolve BeanDefinitionHolder: contains BeanDefinition with name and aliases.
BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;
return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());
}
else if (value instanceof BeanDefinition) {
// Resolve plain BeanDefinition, without contained name: use dummy name.
BeanDefinition bd = (BeanDefinition) value;
String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR +
ObjectUtils.getIdentityHexString(bd);
return resolveInnerBean(argName, innerBeanName, bd);
}
}
@Nullable
private Object resolveInnerBean(Object argName, String innerBeanName, BeanDefinition innerBd) {
RootBeanDefinition mbd = null;
try {
// 获取内部bean的bean定义
mbd = this.beanFactory.getMergedBeanDefinition(innerBeanName, innerBd, this.beanDefinition);
// 检查给定的 bean 名称是否唯一。 如果还不是唯一的,添加计数器 - 增加计数器直到名称是唯一的。
String actualInnerBeanName = innerBeanName;
if (mbd.isSingleton()) {
actualInnerBeanName = adaptInnerBeanName(innerBeanName);
}
this.beanFactory.registerContainedBean(actualInnerBeanName, this.beanName);
// 保证内部 bean 所依赖的 bean 的初始化。
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dependsOnBean : dependsOn) {
this.beanFactory.registerDependentBean(dependsOnBean, actualInnerBeanName);
this.beanFactory.getBean(dependsOnBean);
}
}
// 现在实际创建内部 bean 实例
Object innerBean = this.beanFactory.createBean(actualInnerBeanName, mbd, null);
if (innerBean instanceof FactoryBean) {
boolean synthetic = mbd.isSynthetic();
innerBean = this.beanFactory.getObjectFromFactoryBean(
(FactoryBean<?>) innerBean, actualInnerBeanName, !synthetic);
}
if (innerBean instanceof NullBean) {
innerBean = null;
}
return innerBean;
}
catch (BeansException ex) {
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Cannot create inner bean '" + innerBeanName + "' " +
(mbd != null && mbd.getBeanClassName() != null ? "of type [" + mbd.getBeanClassName() + "] " : "") +
"while setting " + argName, ex);
}
}
继承类实现流程
测试用例
我们的测试用例如下:
public class Parent {
@Setter
private String s;
}
public class Son extends Parent{
@Setter
private String c;
}
对应的spring配置为:
<?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 id="a" class="org.jdbc.demo.Parent">
<property name="s" value="1232"/>
</bean>
<bean id="b" class="org.jdbc.demo.Son" parent="a">
<property name="c" value="1234"/>
</bean>
</beans>
内部实现流程
走读代码,我们发现在获取bean之前,合并bean定义的流程中如果父bean存在会递归获取对应的父bean定义,通过mbd.overrideFrom(bd)
将属性进行合并最后返回:
protected RootBeanDefinition getMergedBeanDefinition(
String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
throws BeanDefinitionStoreException {
synchronized (this.mergedBeanDefinitions) {
RootBeanDefinition mbd = null;
// 现在检查完全锁定以强制执行相同的合并实例。
if (containingBd == null) {
mbd = this.mergedBeanDefinitions.get(beanName);
}
if (mbd == null) {
//对应bean的父bean为空
if (bd.getParentName() == null) {
//使用给定根 bean 定义的副本。
if (bd instanceof RootBeanDefinition) {
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
}
else {
mbd = new RootBeanDefinition(bd);
}
}
else {
// 如果父bean不为空,则子 bean 定义需要与父 bean 合并。
BeanDefinition pbd;
try {
//根据父beanid找到父bean名称
String parentBeanName = transformedBeanName(bd.getParentName());
//如果要查找的bean和父bean名称不相等
if (!beanName.equals(parentBeanName)) {
//递归查找对应的父bean定义
pbd = getMergedBeanDefinition(parentBeanName);
}
//如果要查找的bean和父bean为同一个bean名称
else {
//获取对应的父bean工厂,并尝试获取合并后的bean定义
BeanFactory parent = getParentBeanFactory();
if (parent instanceof ConfigurableBeanFactory) {
pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
}
else {
throw new NoSuchBeanDefinitionException(parentBeanName,
"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
"': cannot be resolved without an AbstractBeanFactory parent");
}
}
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
}
//具有覆盖值的深拷贝。
mbd = new RootBeanDefinition(pbd);
//将子bean的属性值添加到父bean属性集合中
mbd.overrideFrom(bd);
}
// 如果之前未配置,则设置默认单例范围。
if (!StringUtils.hasLength(mbd.getScope())) {
mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
}
//包含在非单例 bean 中的 bean 本身不能是单例。让我们在这里即时纠正这个问题,因为这可能是外部 bean 的父子合并的结果,在这种情况下,原始的内部 bean 定义将不会继承合并的外部 bean 的单例状态。
if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
mbd.setScope(containingBd.getScope());
}
//暂时缓存合并的 bean 定义(它可能稍后仍会重新合并以获取元数据更改)
if (containingBd == null && isCacheBeanMetadata()) {
this.mergedBeanDefinitions.put(beanName, mbd);
}
}
//返回的是对应bean名称的合并bean定义集合
return mbd;
}
}
从返回的bean定义中我们可以看到,属性集合中已经包含子类和父类的全部属性:
获取bean的流程
从前几篇文章和本文的梳理中,我们已经能够很准确的梳理出bean获取的流程了,如下:
bean获取的入口在AbstractBeanFactory
中,bean创建和属性填充的过程在AbstractAutowireCapableBeanFactory
中,而内部bean和依赖bean的获取则交由BeanDefinitionValueResolver
进行统一处理后,再由AbstractNestablePropertyAccessor
调用PropertyHandler
(由BeanWrapperImpl
实现setValue()
方法)完成属性填充。
BeanFactory
解析
综上,我们也能结合源码,捋清楚bean工厂的类关系和类职责:
由上图,我们可以知道bean工厂定义类了三类操作:
-
第一类:对bean工厂中bean定义相关的操作,对应接口
ListableBeanFactory
-
第二类:对bean工厂中bean对象的初始化操作,对应接口
AutowireCapableBeanFactory
-
第三类:对bean工厂本身的操作,对应接口
HierarchicalBeanFactory
基于上述三类,由衍生出:
-
对bean定义进行解析和获取bean操作,对应接口
ConfigurableBeanFactory
-
读取bean定义并进行bean初始化的操作,对应接口
ConfigurableListableBeanFactory
然后分别由以下类进行实现:
-
Bean定义的解析和Bean的获取,由
AbstractBeanFactory
负责完成 -
Bean的初始化,由
AbstractAutowireCapableBeanFactory
负责完成 -
获取Bean定义以及依赖bean定义获取bean的操作,由
DefaultListableBeanFactory
负责完成
评论区