SF如何使用BeanDefinition达成其目标IoC,我们通过跟踪BeanDefinition使用来了解。
使用起点
跟踪SF初始化过程,第一个点在:DefaultListableBeanFactory.preInstantiateSingletons。如下图:
RootBeanDefinition是运行时Spring BeanFactory使用的bean定义,可能是由多个相互继承的原始BeanDefinition(从配置元数据中解析生成的)合并创建而来。本质上可RootBeanDefinition当做运行时的“统一”bean定义视图。
注:此处生成bd(RootBeanDefinition)并没有传入到方法getBean(beanName),是因为第一次生成后就缓存在beanFactory,下次直接从缓存获得即可。
类-RootBeanDefinition
RootBeanDefinition继承于AbstractBeanDefinition,主要增强或限制:
1、不能有继承(都被合并):setParentName总是null;
2、确定bean解析器,包括注解、反射类型、class、工厂方法和supplier;
3、管理外部管理器:Member、初始化方法和销毁方法等;
@SuppressWarnings("serial")
public class RootBeanDefinition extends AbstractBeanDefinition {
@Override
public String getParentName() {
return null;
}
@Override
public void setParentName(@Nullable String parentName) {
if (parentName != null) {
throw new IllegalArgumentException("Root bean cannot be changed into a child bean with parent reference");
}
}
public void setDecoratedDefinition(@Nullable BeanDefinitionHolder decoratedDefinition) {
this.decoratedDefinition = decoratedDefinition;
}
@Nullable
public BeanDefinitionHolder getDecoratedDefinition() {
return this.decoratedDefinition;
}
public void setQualifiedElement(@Nullable AnnotatedElement qualifiedElement) {
this.qualifiedElement = qualifiedElement;
}
@Nullable
public AnnotatedElement getQualifiedElement() {
return this.qualifiedElement;
}
public void setTargetType(@Nullable ResolvableType targetType) {
this.targetType = targetType;
}
public void setTargetType(@Nullable Class<?> targetType) {
this.targetType = (targetType != null ? ResolvableType.forClass(targetType) : null);
}
@Nullable
public Class<?> getTargetType() {
if (this.resolvedTargetType != null) {
return this.resolvedTargetType;
}
ResolvableType targetType = this.targetType;
return (targetType != null ? targetType.resolve() : null);
}
@Override
public ResolvableType getResolvableType() {
ResolvableType targetType = this.targetType;
if (targetType != null) {
return targetType;
}
ResolvableType returnType = this.factoryMethodReturnType;
if (returnType != null) {
return returnType;
}
Method factoryMethod = this.factoryMethodToIntrospect;
if (factoryMethod != null) {
return ResolvableType.forMethodReturnType(factoryMethod);
}
return super.getResolvableType();
}
@Nullable
public Constructor<?>[] getPreferredConstructors() {
return null;
}
public void setUniqueFactoryMethodName(String name) {
Assert.hasText(name, "Factory method name must not be empty");
setFactoryMethodName(name);
this.isFactoryMethodUnique = true;
}
public void setNonUniqueFactoryMethodName(String name) {
Assert.hasText(name, "Factory method name must not be empty");
setFactoryMethodName(name);
this.isFactoryMethodUnique = false;
}
public boolean isFactoryMethod(Method candidate) {
return candidate.getName().equals(getFactoryMethodName());
}
public void setResolvedFactoryMethod(@Nullable Method method) {
this.factoryMethodToIntrospect = method;
if (method != null) {
setUniqueFactoryMethodName(method.getName());
}
}
@Nullable
public Method getResolvedFactoryMethod() {
return this.factoryMethodToIntrospect;
}
@Override
public void setInstanceSupplier(@Nullable Supplier<?> supplier) {
super.setInstanceSupplier(supplier);
Method factoryMethod = (supplier instanceof InstanceSupplier<?> instanceSupplier ?
instanceSupplier.getFactoryMethod() : null);
if (factoryMethod != null) {
setResolvedFactoryMethod(factoryMethod);
}
}
public void markAsPostProcessed() {
synchronized (this.postProcessingLock) {
this.postProcessed = true;
}
}
public void registerExternallyManagedConfigMember(Member configMember) {
synchronized (this.postProcessingLock) {
if (this.externallyManagedConfigMembers == null) {
this.externallyManagedConfigMembers = new LinkedHashSet<>(1);
}
this.externallyManagedConfigMembers.add(configMember);
}
}
public boolean isExternallyManagedConfigMember(Member configMember) {
synchronized (this.postProcessingLock) {
return (this.externallyManagedConfigMembers != null &&
this.externallyManagedConfigMembers.contains(configMember));
}
}
public Set<Member> getExternallyManagedConfigMembers() {
synchronized (this.postProcessingLock) {
return (this.externallyManagedConfigMembers != null ?
Collections.unmodifiableSet(new LinkedHashSet<>(this.externallyManagedConfigMembers)) :
Collections.emptySet());
}
}
public void registerExternallyManagedInitMethod(String initMethod) {
synchronized (this.postProcessingLock) {
if (this.externallyManagedInitMethods == null) {
this.externallyManagedInitMethods = new LinkedHashSet<>(1);
}
this.externallyManagedInitMethods.add(initMethod);
}
}
public boolean isExternallyManagedInitMethod(String initMethod) {
synchronized (this.postProcessingLock) {
return (this.externallyManagedInitMethods != null &&
this.externallyManagedInitMethods.contains(initMethod));
}
}
boolean hasAnyExternallyManagedInitMethod(String initMethod) {
synchronized (this.postProcessingLock) {
if (isExternallyManagedInitMethod(initMethod)) {
return true;
}
if (this.externallyManagedInitMethods != null) {
for (String candidate : this.externallyManagedInitMethods) {
int indexOfDot = candidate.lastIndexOf('.');
if (indexOfDot >= 0) {
String methodName = candidate.substring(indexOfDot + 1);
if (methodName.equals(initMethod)) {
return true;
}
}
}
}
return false;
}
}
public Set<String> getExternallyManagedInitMethods() {
synchronized (this.postProcessingLock) {
return (this.externallyManagedInitMethods != null ?
Collections.unmodifiableSet(new LinkedHashSet<>(this.externallyManagedInitMethods)) :
Collections.emptySet());
}
}
public void resolveDestroyMethodIfNecessary() {
setDestroyMethodNames(DisposableBeanAdapter
.inferDestroyMethodsIfNecessary(getResolvableType().toClass(), this));
}
public void registerExternallyManagedDestroyMethod(String destroyMethod) {
synchronized (this.postProcessingLock) {
if (this.externallyManagedDestroyMethods == null) {
this.externallyManagedDestroyMethods = new LinkedHashSet<>(1);
}
this.externallyManagedDestroyMethods.add(destroyMethod);
}
}
public boolean isExternallyManagedDestroyMethod(String destroyMethod) {
synchronized (this.postProcessingLock) {
return (this.externallyManagedDestroyMethods != null &&
this.externallyManagedDestroyMethods.contains(destroyMethod));
}
}
boolean hasAnyExternallyManagedDestroyMethod(String destroyMethod) {
synchronized (this.postProcessingLock) {
if (isExternallyManagedDestroyMethod(destroyMethod)) {
return true;
}
if (this.externallyManagedDestroyMethods != null) {
for (String candidate : this.externallyManagedDestroyMethods) {
int indexOfDot = candidate.lastIndexOf('.');
if (indexOfDot >= 0) {
String methodName = candidate.substring(indexOfDot + 1);
if (methodName.equals(destroyMethod)) {
return true;
}
}
}
}
return false;
}
}
public Set<String> getExternallyManagedDestroyMethods() {
synchronized (this.postProcessingLock) {
return (this.externallyManagedDestroyMethods != null ?
Collections.unmodifiableSet(new LinkedHashSet<>(this.externallyManagedDestroyMethods)) :
Collections.emptySet());
}
}
@Override
public RootBeanDefinition cloneBeanDefinition() {
return new RootBeanDefinition(this);
}
@Override
public boolean equals(@Nullable Object other) {
return (this == other || (other instanceof RootBeanDefinition && super.equals(other)));
}
@Override
public String toString() {
return "Root bean: " + super.toString();
}
}
方法-getMergedLocalBeanDefinition(String beanName)
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null && !mbd.stale) {
return mbd;
}
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
throws BeanDefinitionStoreException {
return getMergedBeanDefinition(beanName, bd, null);
}
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;
if (bd.getParentName() == null) {
if (bd instanceof RootBeanDefinition rootBeanDef) {
mbd = rootBeanDef.cloneBeanDefinition();
}
else {
mbd = new RootBeanDefinition(bd);
}
}
else {
BeanDefinition pbd;
try {
String parentBeanName = transformedBeanName(bd.getParentName());
if (!beanName.equals(parentBeanName)) {
pbd = getMergedBeanDefinition(parentBeanName);
}
else {
if (getParentBeanFactory() instanceof ConfigurableBeanFactory parent) {
pbd = 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);
}
mbd = new RootBeanDefinition(pbd);
mbd.overrideFrom(bd);
}
if (!StringUtils.hasLength(mbd.getScope())) {
mbd.setScope(SCOPE_SINGLETON);
}
if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
mbd.setScope(containingBd.getScope());
}
if (containingBd == null && isCacheBeanMetadata()) {
this.mergedBeanDefinitions.put(beanName, mbd);
}
}
if