相关文章java
大多数的方法都能从它的名字知道它是干啥的、都能在 XML 配置文件中找到对应的配置项缓存
大部分的实现是落在 AbstractBeanDefinition 中、里面的逻辑也并非特别的复杂、毕竟只是一些 get/set 方法架构
对于它的三个子类 GenericBeanDefinition RootBeanDefinition ChildBeanDefinition 其实本质上来讲、它们并没有太大的区别、它们都继承了 AbstractBeanDefinition 、在它们各自的类中、并无什么太大的特殊的逻辑、某种程度上来讲、它们能够说是差异很是小的框架
咱们在 Spring 容器初始化的时候、读取 XML 配置文件并注册 BeanDefinition 、这个BeanDefinition 是子类中的哪一个类呢ide
// 解释 bean 标签的时候
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
复制代码
public static AbstractBeanDefinition createBeanDefinition( @Nullable String parentName, @Nullable String className, @Nullable ClassLoader classLoader) throws ClassNotFoundException {
GenericBeanDefinition bd = new GenericBeanDefinition();
bd.setParentName(parentName);
if (className != null) {
if (classLoader != null) {
bd.setBeanClass(ClassUtils.forName(className, classLoader));
}
else {
bd.setBeanClassName(className);
}
}
return bd;
}
复制代码
最终它会落到这个工具类里面、建立的都是 GenericBeanDefinition工具
而在 BeanDefinitionRegistry 的实现类中、都是如此存储的post
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
复制代码
咱们也是可使用其余的 BeanDefinition 的子类注册ui
而咱们在 getBean 的流程中的时候、当咱们没法在三级缓存中获取到 bean 的时候、就开始了建立 bean 的流程、这个时候、就要从 beanDefinition 中获取相关信息建立 beanthis
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
// Quick check on the concurrent map first, with minimal locking.
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null && !mbd.stale) {
return mbd;
}
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
复制代码
咱们能够在 AbstractBeanFactory 中找到spa
private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap<>(256);
复制代码
能够看到 Map 中的 value 的类型是 RootBeanDefinition
若是你在定义中存在了父子 bean、或者更加具体的说、就是在 BeanDefinition 中、你的parentName 不为空、做为子 bean、你就要合成父 bean 的一些属性
synchronized (this.mergedBeanDefinitions) {
RootBeanDefinition mbd = null;
RootBeanDefinition previous = null;
if (containingBd == null) {
mbd = this.mergedBeanDefinitions.get(beanName);
}
if (mbd == null || mbd.stale) {
previous = mbd;
if (bd.getParentName() == null) {
// Use copy of given root bean definition.
if (bd instanceof RootBeanDefinition) {
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
} else {
mbd = new RootBeanDefinition(bd);
}
} else {
// Child bean definition: needs to be merged with parent.
BeanDefinition pbd;
......................
// Deep copy with overridden values.
mbd = new RootBeanDefinition(pbd);
mbd.overrideFrom(bd);
}
........
if (containingBd == null && isCacheBeanMetadata()) {
this.mergedBeanDefinitions.put(beanName, mbd);
}
}
return mbd;
}
复制代码
貌似到目前为止、咱们仍是没有看到 ChildBeanDefinition 使用的场景
貌似确实没啥用是吧在整一个 Spring 框架中、个人版本 5.2
可是呢、其实咱们能够手动的建立一个 BeanDefiniton 注册给 Spring
DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
rootBeanDefinition.setBeanClass(Company.class);
rootBeanDefinition.getPropertyValues().add("name", "XX");
rootBeanDefinition.getPropertyValues().add("numberOfPeople", "1000");
defaultListableBeanFactory.registerBeanDefinition("rootCompany", rootBeanDefinition);
ChildBeanDefinition childBeanDefinition = new ChildBeanDefinition("rootCompany");
defaultListableBeanFactory.registerBeanDefinition("childCompany", childBeanDefinition);
System.out.println(defaultListableBeanFactory.getBean("rootCompany"));
System.out.println(defaultListableBeanFactory.getBean("childCompany"));
System.out.println(defaultListableBeanFactory.getBean("rootCompany") == defaultListableBeanFactory.getBean("childCompany"));
复制代码
其实在 RootBeanDefinition 和 ChildBeanDefinition 中咱们看到注释说、其实首选是 GenericBeanDefinition 、由于 RootBeanDefinition 不可以指定 parentName、而 ChildBeanDefinition 必须有 parentName、这在使用上是很是不灵活的
或许这就是 GenericBeanDefinition 出现的缘由吧
在 AbstractAutowireCapableBeanFactory#doCreateBean 中
在建立好了一个 bean 的时候(不完整的 bean ),会对 MergedBeanDefinitionPostProcessor 的 postProcessMergedBeanDefinition 进行回调、这个时候是比加入第三级缓存以前早一点
defaultListableBeanFactory.addBeanPostProcessor(new MergedBeanDefinitionPostProcessor() {
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
System.out.println("beanName:" + beanName);
}
});
复制代码