在ApplicationContext的refresh方法中,finishBeanFactoryInitialization(beanFactory)这一步是初始化剩余的非懒加载的单例bean,之后会调用BeanFactory的preInstantiateSingletons()方法进行这些bean的加载工作。
在preInstantiateSingletons方法中,首先会从beanDefinitionNames集合中获取所有的beanName,之后会循环进行getBean。
但是在getBean之前,会有一个BeanDefinition的合并动作getMergedLocalBeanDefinition(beanName),对要get的bean的定义先进行合并。
合并的原因
在GenericBeanDefinition,ChildBeanDefinition中有一个parentName属性,表示该BeanDefinition的父BeanDefinition,如果该bean在定义中设置了parentName,那么在实例化之前会进行这两个BeanDefinition的合并。
一、例子
定义子类
@Data
public class ChildBean {
private String name;
private String age;
private String address;
}
定义父类
@Data
public class FatherBean {
private String name;
private String age;
private String address;
}
public class AnnotatedTestMain {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
// 将FatherBean注册到上下文的BeanFactory中
RootBeanDefinition fatherBean = new RootBeanDefinition();
fatherBean.setBeanClass(FatherBean.class);
fatherBean.getPropertyValues().add("name", "父亲");
fatherBean.getPropertyValues().add("age", "60");
fatherBean.getPropertyValues().add("address", "北京");
context.registerBeanDefinition("fatherBean", fatherBean);
// 将ChildBean注册到上下文的BeanFactory中
GenericBeanDefinition childBean = new GenericBeanDefinition();
childBean.setBeanClass(ChildBean.class);
childBean.getPropertyValues().add("name", "儿子");
childBean.setParentName("fatherBean");
context.registerBeanDefinition("childBean", childBean);
context.refresh();
System.out.println(context.getBean(ChildBean.class));
System.out.println(context.getBean(FatherBean.class));
}
ChildBean会继承FatherBean相同属性的值(age和address)
打印结果:
ChildBean(name=儿子, age=60, address=北京)
FatherBean(name=父亲, age=60, address=北京)
Process finished with exit code 0
二、AbstractBeanFactory中对于bean定义合并的代码逻辑
//返回一个合并的 RootBeanDefinition,如果该bean定义是一个子bean定义,则遍历父bean定义
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
//先从mergedBeanDefinitions容器中取
//如果有,表示该bean定义已经合并过了,则就直接返回;如果没有,则进行合并
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null) {
return mbd;
}
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
/*
* 如果该bean定义是子bean定义,则通过与父级合并返回给定顶级 bean 的 RootBeanDefinition
* @param beanName bean定义的名称
* @param bd 原始的bean定义(Root/ChildBeanDefinition)
* @return 给定bean的(可能合并的)RootBeanDefinition
* @throws BeanDefinitionStoreException in case of an invalid bean definition
*/
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
throws BeanDefinitionStoreException {
return getMergedBeanDefinition(beanName, bd, null);
}
/**
* 返回一个合并的RootBeanDefinition,如果该bean定义是一个子bean定义,则合并父bean定义
* @param bean定义的名称
* @param bd 原始的bean定义(Root/ChildBeanDefinition)
* @param containingBd 如果是内部bean,则包含bean定义,如果是顶级 bean,则为null
* @return 给定bean的(可能合并的)RootBeanDefinition
* @throws BeanDefinitionStoreException in case of an invalid bean definition
*/
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定义没有parent,则不进行合并,返回包装后的RootBeanDefinition
if (bd.getParentName() == null) {
//如果该bean定义是RootBeanDefinition,则直接克隆一份BeanDefinition
if (bd instanceof RootBeanDefinition) {
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
}
//如果不是RootBeanDefinition,则包装为RootBeanDefinition
else {
mbd = new RootBeanDefinition(bd);
}
}
//如果该bean定义有parent
else {
// Child bean definition: needs to be merged with parent.
BeanDefinition pbd;
try {
String parentBeanName = transformedBeanName(bd.getParentName());
//如果parentName不是当前的beanName,则获取父bean合并后的bean定义
if (!beanName.equals(parentBeanName)) {
//递归调用进行父bean定义的合并
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 an AbstractBeanFactory parent");
}
}
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
}
// Deep copy with overridden values.
mbd = new RootBeanDefinition(pbd);
//1.1 覆盖bean信息,用子bean定义中的属性,方法覆盖父bean定义中的属性,方法
mbd.overrideFrom(bd);
}
// Set default singleton scope, if not configured before.
if (!StringUtils.hasLength(mbd.getScope())) {
mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
}
// A bean contained in a non-singleton bean cannot be a singleton itself.
// Let's correct this on the fly here, since this might be the result of
// parent-child merging for the outer bean, in which case the original inner bean
// definition will not have inherited the merged outer bean's singleton status.
if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
mbd.setScope(containingBd.getScope());
}
//将合并后的bean定义放入到缓存中
if (containingBd == null && isCacheBeanMetadata()) {
this.mergedBeanDefinitions.put(beanName, mbd);
}
}
return mbd;
}
}
1.1覆盖Bean信息
AbstractBeanDefinition中对bean定义的覆盖
/**
* Override settings in this bean definition (presumably a copied parent
* from a parent-child inheritance relationship) from the given bean
* definition (presumably the child).
* <ul>
* <li>Will override beanClass if specified in the given bean definition.
* <li>Will always take {@code abstract}, {@code scope},
* {@code lazyInit}, {@code autowireMode}, {@code dependencyCheck},
* and {@code dependsOn} from the given bean definition.
* <li>Will add {@code constructorArgumentValues}, {@code propertyValues},
* {@code methodOverrides} from the given bean definition to existing ones.
* <li>Will override {@code factoryBeanName}, {@code factoryMethodName},
* {@code initMethodName}, and {@code destroyMethodName} if specified
* in the given bean definition.
* </ul>
*/
public void overrideFrom(BeanDefinition other) {
//如有直接覆盖BeanClassName
if (StringUtils.hasLength(other.getBeanClassName())) {
setBeanClassName(other.getBeanClassName());
}
//如有作用域直接覆盖作用域
if (StringUtils.hasLength(other.getScope())) {
setScope(other.getScope());
}
//覆盖是否抽象
setAbstract(other.isAbstract());
//覆盖是否懒加载
setLazyInit(other.isLazyInit());
//覆盖工厂名
if (StringUtils.hasLength(other.getFactoryBeanName())) {
setFactoryBeanName(other.getFactoryBeanName());
}
//覆盖工厂方法名
if (StringUtils.hasLength(other.getFactoryMethodName())) {
setFactoryMethodName(other.getFactoryMethodName());
}
setRole(other.getRole());
setSource(other.getSource());
//拷贝属性
copyAttributesFrom(other);
if (other instanceof AbstractBeanDefinition) {
AbstractBeanDefinition otherAbd = (AbstractBeanDefinition) other;
if (otherAbd.hasBeanClass()) {
setBeanClass(otherAbd.getBeanClass());
}
if (otherAbd.hasConstructorArgumentValues()) {
getConstructorArgumentValues().addArgumentValues(other.getConstructorArgumentValues());
}
if (otherAbd.hasPropertyValues()) {
getPropertyValues().addPropertyValues(other.getPropertyValues());
}
if (otherAbd.hasMethodOverrides()) {
getMethodOverrides().addOverrides(otherAbd.getMethodOverrides());
}
setAutowireMode(otherAbd.getAutowireMode());
setDependencyCheck(otherAbd.getDependencyCheck());
setDependsOn(otherAbd.getDependsOn());
setAutowireCandidate(otherAbd.isAutowireCandidate());
setPrimary(otherAbd.isPrimary());
copyQualifiersFrom(otherAbd);
setInstanceSupplier(otherAbd.getInstanceSupplier());
setNonPublicAccessAllowed(otherAbd.isNonPublicAccessAllowed());
setLenientConstructorResolution(otherAbd.isLenientConstructorResolution());
if (otherAbd.getInitMethodName() != null) {
setInitMethodName(otherAbd.getInitMethodName());
setEnforceInitMethod(otherAbd.isEnforceInitMethod());
}
if (otherAbd.getDestroyMethodName() != null) {
setDestroyMethodName(otherAbd.getDestroyMethodName());
setEnforceDestroyMethod(otherAbd.isEnforceDestroyMethod());
}
setSynthetic(otherAbd.isSynthetic());
setResource(otherAbd.getResource());
}
else {
getConstructorArgumentValues().addArgumentValues(other.getConstructorArgumentValues());
getPropertyValues().addPropertyValues(other.getPropertyValues());
setResourceDescription(other.getResourceDescription());
}
}
protected void copyAttributesFrom(AttributeAccessor source) {
Assert.notNull(source, "Source must not be null");
String[] attributeNames = source.attributeNames();
for (String attributeName : attributeNames) {
setAttribute(attributeName, source.getAttribute(attributeName));
}
}