在spring中BeanDefinition是一个接口,下面也有很多的实现类
大致如下
BeanDefinition
AbstractBeanDefinition
RootBeanDefinition 最终每个BeanDefinition都是一个 RootBeanDefinition
ChildBeanDefinition 现在不用了废弃,现在使用的都是 GenericBeanDefinition
GenericBeanDefinition 我们定义的一般都是 GenericBeanDefinition
ScannedGenericBeanDefinition 是GenericBeanDefinition的一个子类,表示是通过scanner扫描出来的Bean
AnnotatedGenericBeanDefinition 是GenericBeanDefinition的一个子类,表示是通过reader注册的Bean
beanClass bean对应的类,是一个object类型,在还没有实例化单例Bean的时候放入的是类全限定名,实例化后就是class
scope 单例 多例等
abstractFlag 标志无法实例化
lazyInit 懒加载
autowireMode AUTOWIRE_NO,AUTOWIRE_BY_NAME,AUTOWIRE_BY_TYPE,AUTOWIRE_CONSTRUCTOR,AUTOWIRE_AUTODETECT
dependsOn 依赖于其它bean,其它bean会先初始化
instanceSupplier 对象来源于Supplier
factoryBeanName factoryBean的名字
factoryMethodName @Bean的时候会有值
initMethodName 初始化方法
destroyMethodName 销毁方法
在spring中并没有该类的定义,但却十分重要
private final Map
一般来说我们的bean都是GenericBeanDefinition,其实也是RootBeanDefinition,但是在xml方式下,可以设置一个BeanDefinition为abstract的,可供其它bean继承它,从而得到自己没有定义的属性
例如
spring.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"
>
<bean id="abs" scope="prototype" abstract="true"/>
<bean id="userBean" class="com.shura.beans.UserBean" parent="abs"/>
beans>
使用xml方式
public class Application {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
System.out.println(context.getBean(UserBean.class));
System.out.println(context.getBean(UserBean.class));
System.out.println(context.getBean(UserBean.class));
}
}
输出
com.shura.beans.UserBean@7506e922
com.shura.beans.UserBean@4ee285c6
com.shura.beans.UserBean@621be5d1
从上面例子可以看出,定义了一个abs的抽象 BeanDefinition userBean继承了它,从而获得了多例属性
那么在注册bean的时候就势必要找出父BeanDefinition,继承属性,于是就有了mergedBeanDefinitions
在实例化单例Bean的时候就有这一步骤
方法
org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
下面是简化的源码
protected RootBeanDefinition getMergedBeanDefinition(
String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
throws BeanDefinitionStoreException {
synchronized (this.mergedBeanDefinitions) {
RootBeanDefinition mbd = null;
RootBeanDefinition previous = null;
if (containingBd == null) {
mbd = this.mergedBeanDefinitions.get(beanName);
}
// 如果合并过就跳过
if (mbd == null || mbd.stale) {
previous = mbd;
// 是否有parent,大部分都是进入该分支,如果进入该分支,那么本身的BeanDefinition就是RootBeanDefinition
if (bd.getParentName() == null) {
if (bd instanceof RootBeanDefinition) {
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
} else {
mbd = new RootBeanDefinition(bd);
}
} else {
// 进入这里表示有父BeanDefinition parent != null
BeanDefinition pbd;
try {
String parentBeanName = transformedBeanName(bd.getParentName());
if (!beanName.equals(parentBeanName)) {
// 寻找父BeanDefinition的父BeanDefinition,知道找不到
pbd = getMergedBeanDefinition(parentBeanName);
} else {
// 抛出异常
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 a ConfigurableBeanFactory parent");
}
}
} catch (NoSuchBeanDefinitionException ex) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
}
// 覆盖属性,得到一个新的RootBeanDefinition
mbd = new RootBeanDefinition(pbd);
mbd.overrideFrom(bd);
}
if (!StringUtils.hasLength(mbd.getScope())) {
// 默认单例
mbd.setScope(SCOPE_SINGLETON);
}
if (containingBd == null && isCacheBeanMetadata()) {
// 缓存起来
this.mergedBeanDefinitions.put(beanName, mbd);
}
}
if (previous != null) {
// copy属性
copyRelevantMergedBeanDefinitionCaches(previous, mbd);
}
return mbd;
}
}
上面就是merge的逻辑,大致就是,如果有父BeanDefinition就合并属性得到一个新的RootBeanDefinition,返回
本文主要介绍了BeanDefinition以及合并的过程,下一节介绍FactoryBean
欢迎关注,学习不迷路!