-
DefaultListableBeanFactory是Spring的默认实现,是ConfigurableListableBeanFactory和BeanDefinitionRegistry接口的实现,它是一个基于bean定义元数据的充分功能的bean工厂,并通过后置处理器进行可扩展。
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {}
getBean(Class<T> requiredType, @Nullable Object... args)
这个方法的作用是提供了一种更便捷的方式来获取bean,而无需手动进行类型转换和判空等操作。通过使用泛型,可以确保返回的bean实例与指定的类型相匹配,避免了强制类型转换的风险和麻烦。
调用resolveBean方法解析指定类型的bean。resolveBean方法使用ResolvableType.forRawClass(requiredType)创建一个ResolvableType对象,表示所需类型。然后传入args和false参数,执行解析过程。解析bean的过程包括查找bean定义并创建bean实例。
java
@Override
public <T> T getBean(Class<T> requiredType, @Nullable Object... args) throws BeansException {
Assert.notNull(requiredType, "Required type must not be null");
Object resolved = resolveBean(ResolvableType.forRawClass(requiredType), args, false);
if (resolved == null) {
throw new NoSuchBeanDefinitionException(requiredType);
}
return (T) resolved;
}
containsBeanDefinition(String beanName)
在一个大型的应用程序中,可能有很多不同的bean被定义在Spring的IoC容器中。而这些bean的定义信息被存储在DefaultListableBeanFactory类内部的一个称为beanDefinitionMap的数据结构中。
这个方法在DefaultListableBeanFactory中的设计目的是为了提供一种便捷的方式检查是否存在具有给定名称的bean定义。它增强了应用程序开发者对Spring框架的控制和灵活性,帮助开发者更有效地使用和管理bean对象。
java
@Override
public boolean containsBeanDefinition(String beanName) {
Assert.notNull(beanName, "Bean name must not be null");
return this.beanDefinitionMap.containsKey(beanName);
}
- resolveBean(ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull)
resolveBean方法提供了一种灵活且递归的解析机制,使得用户在多层次的bean定义结构中能够方便地获取指定类型的bean实例。
该方法首先尝试调用resolveNamedBean方法,根据requiredType和args参数来查找匹配的bean定义。如果成功找到,则返回对应的bean实例。
如果在当前DefaultListableBeanFactory中未找到匹配的bean定义,它会检查父级BeanFactory的类型。如果父级BeanFactory是DefaultListableBeanFactory的实例,则递归调用其resolveBean方法来尝试从父级BeanFactory中获取指定类型的bean实例。
如果父级BeanFactory不是DefaultListableBeanFactory的实例,而是其他类型的BeanFactory,则使用父级BeanFactory提供的ObjectProvider来获取指定类型的bean实例。
java
@Nullable
private <T> T resolveBean(ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) {
NamedBeanHolder<T> namedBean = resolveNamedBean(requiredType, args, nonUniqueAsNull);
if (namedBean != null) {
return namedBean.getBeanInstance();
}
BeanFactory parent = getParentBeanFactory();
if (parent instanceof DefaultListableBeanFactory) {
return ((DefaultListableBeanFactory) parent).resolveBean(requiredType, args, nonUniqueAsNull);
}
else if (parent != null) {
ObjectProvider<T> parentProvider = parent.getBeanProvider(requiredType);
if (args != null) {
return parentProvider.getObject(args);
}
else {
return (nonUniqueAsNull ? parentProvider.getIfUnique() : parentProvider.getIfAvailable());
}
}
return null;
}
-
getBeansOfType(
@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
这个方法用于获取指定类型的所有bean实例,并将其封装成一个Map,其中key为bean名称,value为对应的bean实例。
getBeansOfType方法的主要功能是根据给定的类型,遍历所有的bean定义,获取满足条件的bean名称数组,然后通过调用getBean方法逐个获取相应的bean实例,并将其封装到结果Map中。
该方法还支持包含非单例bean和懒加载的bean,以及允许提前初始化bean的配置。这样可以灵活地满足不同场景下的需求。
首先,接收三个参数:type(要获取的bean类型)、includeNonSingletons(是否包含非单例bean)和allowEagerInit(是否允许提前初始化)。
然后,调用getBeanNamesForType方法获取指定类型的bean名称数组。
接着,创建一个空的LinkedHashMap来存储结果,确保结果的顺序与遍历的顺序一致。
对于每个beanName,通过调用getBean(beanName)方法获取对应的bean实例,并进行如下处理:
-
如果beanInstance不是NullBean的实例,则将beanName和beanInstance添加到结果中。
-
如果在获取bean实例时抛出了BeanCreationException异常,则检查异常的最具体原因。如果原因是BeanCurrentlyInCreationException,表示存在循环引用的情况。
-
如果被循环引用的bean正在创建中,则忽略这个匹配,并记录异常。这样可以避免循环引用导致的死循环。
-
如果被循环引用的bean已经创建完成,则抛出异常,以避免无限递归。
-
最后,返回封装了指定类型的所有bean实例的Map。
java
@Override
@SuppressWarnings("unchecked")
public <T> Map<String, T> getBeansOfType(
@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit) throws BeansException {
String[] beanNames = getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
Map<String, T> result = CollectionUtils.newLinkedHashMap(beanNames.length);
for (String beanName : beanNames) {
try {
Object beanInstance = getBean(beanName);
if (!(beanInstance instanceof NullBean)) {
result.put(beanName, (T) beanInstance);
}
}
catch (BeanCreationException ex) {
Throwable rootCause = ex.getMostSpecificCause();
if (rootCause instanceof BeanCurrentlyInCreationException) {
BeanCreationException bce = (BeanCreationException) rootCause;
String exBeanName = bce.getBeanName();
if (exBeanName != null && isCurrentlyInCreation(exBeanName)) {
if (logger.isTraceEnabled()) {
logger.trace("Ignoring match to currently created bean '" + exBeanName + "': " +
ex.getMessage());
}
onSuppressedException(ex);
// Ignore: indicates a circular reference when autowiring constructors.
// We want to find matches other than the currently created bean itself.
continue;
}
}
throw ex;
}
}
return result;
}
- getBeanNamesForAnnotation(Class<? extends Annotation> annotationType)
这个方法用于根据给定的注解类型获取所有被标注该注解的bean名称数组。
首先,接收一个参数annotationType(要查找的注解类型)。
然后,创建一个空的List<String>
来存储满足条件的bean名称。
接着,对所有的beanDefinitionNames进行遍历。对于每个beanName,会进行如下判断和处理:
-
通过beanName获取对应的BeanDefinition对象bd。
-
如果bd不为null,并且当前bean不是抽象的(!bd.isAbstract()),并且通过findAnnotationOnBean(beanName, annotationType)方法能够找到该bean上的注解,则将这个bean的名称添加到结果集result中。
-
对于通过手动注册的单例bean(manualSingletonNames),也进行相同的判断和处理。
最后,将结果集result转换成字符串数组,并返回。
当我们需要获取所有被特定注解标注的bean名称时,可以使用该方法快速获取结果,并进行相应的处理,如进一步获取或操作这些bean实例。
java
@Override
public String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType) {
List<String> result = new ArrayList<>();
for (String beanName : this.beanDefinitionNames) {
BeanDefinition bd = this.beanDefinitionMap.get(beanName);
if (bd != null && !bd.isAbstract() && findAnnotationOnBean(beanName, annotationType) != null) {
result.add(beanName);
}
}
for (String beanName : this.manualSingletonNames) {
if (!result.contains(beanName) && findAnnotationOnBean(beanName, annotationType) != null) {
result.add(beanName);
}
}
return StringUtils.toStringArray(result);
}
getBeansWithAnnotation(Class<? extends Annotation> annotationType)
这是获取带有指定注解的Bean实例的方法。
具体的实现步骤如下:
- 调用
getBeanNamesForAnnotation(annotationType)
方法,该方法是Spring框架提供的,用于获取在容器中带有指定注解的Bean名称。 - 将获取的Bean名称存入
beanNames
数组中。 - 创建一个空的LinkedHashMap,用于存储最终的结果。
- 遍历
beanNames
数组,对于每个Bean名称,调用getBean(beanName)
方法获取对应的Bean实例。 - 判断获取的Bean实例是否为
NullBean
的实例,如果不是,则将Bean名称和实例存入结果Map中。 - 遍历结束后,返回存有Bean名称和实例的结果Map。
java
@Override
public Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) {
String[] beanNames = getBeanNamesForAnnotation(annotationType);
Map<String, Object> result = CollectionUtils.newLinkedHashMap(beanNames.length);
for (String beanName : beanNames) {
Object beanInstance = getBean(beanName);
if (!(beanInstance instanceof NullBean)) {
result.put(beanName, beanInstance);
}
}
return result;
}
findAnnotationOnBean(String beanName, Class<A> annotationType)
该方法根据给定的beanName和annotationType,在对应的Bean实例上查找注解,并返回注解的实例。
java
@Override
@Nullable
public <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
throws NoSuchBeanDefinitionException {
return findAnnotationOnBean(beanName, annotationType, true);
}
findAnnotationOnBean(
String beanName, Class<A> annotationType, boolean allowFactoryBeanInit)
该方法根据给定的beanName、annotationType和allowFactoryBeanInit,在对应的Bean实例上查找并合并注解,并返回注解的实例。
具体的实现步骤如下:
- 调用
findMergedAnnotationOnBean(beanName, annotationType, allowFactoryBeanInit)
方法,传入beanName、annotationType和allowFactoryBeanInit参数。 - 在
findMergedAnnotationOnBean()
方法中,根据beanName获取对应的Bean实例。 - 在获取到的Bean实例上使用
annotationType
作为参数调用findMergedAnnotation()
方法,该方法是Spring框架提供的方法,用于查找并合并指定注解。 - 调用
synthesize()
方法,对合并后的注解进行处理,将其转化为一个具体的注解实例。 - 使用
orElse(null)
方法,如果合并后的注解实例存在,则返回该实例;否则,返回null。
java
@Override
@Nullable
public <A extends Annotation> A findAnnotationOnBean(
String beanName, Class<A> annotationType, boolean allowFactoryBeanInit)
throws NoSuchBeanDefinitionException {
return findMergedAnnotationOnBean(beanName, annotationType, allowFactoryBeanInit)
.synthesize(MergedAnnotation::isPresent).orElse(null);
}
findMergedAnnotationOnBean(
String beanName, Class<A> annotationType, boolean allowFactoryBeanInit)
这个方法用于在指定的Bean实例上查找并合并(merged)指定注解。
具体的实现步骤如下:
- 首先,通过调用
getType(beanName, allowFactoryBeanInit)
方法获取Bean的类型。 - 如果beanType不为null,则使用
MergedAnnotations.from(beanType, SearchStrategy.TYPE_HIERARCHY).get(annotationType)
查找并合并指定注解。如果找到注解且存在,则返回该注解。 - 如果beanType为null,表示无法获取到Bean的类型,接下来继续处理。
- 如果包含名为beanName的Bean定义(bean definition),则获取该Bean定义,并判断是否有Bean类信息(beanClass)。如果有,则获取该Bean类的类型(beanClass)。
- 如果beanClass与之前获取的beanType不同,说明存在代理(proxy)或其他原因导致的类型不匹配,再次使用
MergedAnnotations.from(beanClass, SearchStrategy.TYPE_HIERARCHY).get(annotationType)
查找并合并指定注解。如果找到注解且存在,则返回该注解。 - 如果存在名为factoryMethod的工厂方法,则使用
MergedAnnotations.from(factoryMethod, SearchStrategy.TYPE_HIERARCHY).get(annotationType)
查找并合并指定注解。如果找到注解且存在,则返回该注解。 - 如果以上步骤都没有找到指定注解,则返回一个"missing"状态的MergedAnnotation。
java
private <A extends Annotation> MergedAnnotation<A> findMergedAnnotationOnBean(
String beanName, Class<A> annotationType, boolean allowFactoryBeanInit) {
Class<?> beanType = getType(beanName, allowFactoryBeanInit);
if (beanType != null) {
MergedAnnotation<A> annotation =
MergedAnnotations.from(beanType, SearchStrategy.TYPE_HIERARCHY).get(annotationType);
if (annotation.isPresent()) {
return annotation;
}
}
if (containsBeanDefinition(beanName)) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// Check raw bean class, e.g. in case of a proxy.
if (bd.hasBeanClass()) {
Class<?> beanClass = bd.getBeanClass();
if (beanClass != beanType) {
MergedAnnotation<A> annotation =
MergedAnnotations.from(beanClass, SearchStrategy.TYPE_HIERARCHY).get(annotationType);
if (annotation.isPresent()) {
return annotation;
}
}
}
// Check annotations declared on factory method, if any.
Method factoryMethod = bd.getResolvedFactoryMethod();
if (factoryMethod != null) {
MergedAnnotation<A> annotation =
MergedAnnotations.from(factoryMethod, SearchStrategy.TYPE_HIERARCHY).get(annotationType);
if (annotation.isPresent()) {
return annotation;
}
}
}
return MergedAnnotation.missing();
}
registerResolvableDependency(Class<?> dependencyType, @Nullable Object autowiredValue)
这个方法的作用是注册可解析的依赖关系。当系统需要解析自动注入时,会查找并使用已注册的依赖关系来提供对应的注入值。
具体的实现步骤如下:
- 首先,使用断言
Assert.notNull(dependencyType, "Dependency type must not be null")
确保依赖类型不为null,如果依赖类型为null,则抛出异常。 - 接着,判断注入值是否为null。
- 如果注入值不为null,进一步判断注入值是否是ObjectFactory的实例,或者依赖类型是否是注入值的实例。
- 如果注入值不是ObjectFactory的实例,且依赖类型不是注入值的实例,抛出IllegalArgumentException异常,说明该值无效。
- 否则,将依赖类型和注入值存入resolvableDependencies,即注册可解析的依赖关系。
- 注入值为null时,不做任何操作。
java
@Override
public void registerResolvableDependency(Class<?> dependencyType, @Nullable Object autowiredValue) {
Assert.notNull(dependencyType, "Dependency type must not be null");
if (autowiredValue != null) {
if (!(autowiredValue instanceof ObjectFactory || dependencyType.isInstance(autowiredValue))) {
throw new IllegalArgumentException("Value [" + autowiredValue +
"] does not implement specified dependency type [" + dependencyType.getName() + "]");
}
this.resolvableDependencies.put(dependencyType, autowiredValue);
}
}
isAutowireCandidate(String beanName, DependencyDescriptor descriptor)
这个用于判断指定的Bean是否为候选的自动装配(autowire)目标。它会根据给定的beanName、DependencyDescriptor和AutowireCandidateResolver来进行判断。
具体的实现步骤如下:
- 调用
getAutowireCandidateResolver()
方法获取AutowireCandidateResolver的实例。 - 调用重载方法
isAutowireCandidate(beanName, descriptor, getAutowireCandidateResolver())
,传入beanName、descriptor和AutowireCandidateResolver。 - 在
isAutowireCandidate()
方法中,根据beanName和descriptor使用AutowireCandidateResolver的isAutowireCandidate()
方法进行判断。 - 返回判断的结果,即表示该Bean是否为自动装配的候选目标。
java
@Override
public boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor)
throws NoSuchBeanDefinitionException {
return isAutowireCandidate(beanName, descriptor, getAutowireCandidateResolver());
}
isAutowireCandidate(
String beanName, DependencyDescriptor descriptor, AutowireCandidateResolver resolver)
这个方法用于确定指定的Bean定义是否符合自动装配(autowire)的候选条件,可以被注入到其他声明了匹配类型依赖的Bean中。
具体的实现步骤如下:
- 首先,使用
BeanFactoryUtils.transformedBeanName(beanName)
将beanName转换为标准格式。 - 判断容器中是否包含名为bdName的Bean定义。
- 如果存在,调用
isAutowireCandidate(beanName, getMergedLocalBeanDefinition(bdName), descriptor, resolver)
进行判断。 - 如果不存在,继续下面的处理。
- 如果存在,调用
- 再次判断容器中是否包含名为beanName的单例Bean。
- 如果存在,创建一个包含类型信息的RootBeanDefinition,并调用
isAutowireCandidate(beanName, rootBeanDefinition, descriptor, resolver)
进行判断。 - 如果不存在,继续下面的处理。
- 如果存在,创建一个包含类型信息的RootBeanDefinition,并调用
- 获得父级BeanFactory。
- 如果父级BeanFactory是DefaultListableBeanFactory的实例,则将判断任务委托给父级BeanFactory的
isAutowireCandidate()
方法,并返回其结果。 - 如果父级BeanFactory是ConfigurableListableBeanFactory的实例,则调用其
isAutowireCandidate(beanName, descriptor)
方法进行判断。 - 如果父级BeanFactory不属于上述两种情况,则默认返回true,表示该Bean为自动装配候选对象。
- 如果父级BeanFactory是DefaultListableBeanFactory的实例,则将判断任务委托给父级BeanFactory的
java
protected boolean isAutowireCandidate(
String beanName, DependencyDescriptor descriptor, AutowireCandidateResolver resolver)
throws NoSuchBeanDefinitionException {
String bdName = BeanFactoryUtils.transformedBeanName(beanName);
if (containsBeanDefinition(bdName)) {
return isAutowireCandidate(beanName, getMergedLocalBeanDefinition(bdName), descriptor, resolver);
}
else if (containsSingleton(beanName)) {
return isAutowireCandidate(beanName, new RootBeanDefinition(getType(beanName)), descriptor, resolver);
}
BeanFactory parent = getParentBeanFactory();
if (parent instanceof DefaultListableBeanFactory) {
// No bean definition found in this factory -> delegate to parent.
return ((DefaultListableBeanFactory) parent).isAutowireCandidate(beanName, descriptor, resolver);
}
else if (parent instanceof ConfigurableListableBeanFactory) {
// If no DefaultListableBeanFactory, can't pass the resolver along.
return ((ConfigurableListableBeanFactory) parent).isAutowireCandidate(beanName, descriptor);
}
else {
return true;
}
}
isAutowireCandidate(String beanName, RootBeanDefinition mbd,
DependencyDescriptor descriptor, AutowireCandidateResolver resolver)
这个用于判断指定的Bean定义是否符合自动装配(autowire)的候选条件,可以被注入到其他声明了匹配类型依赖的Bean中。
具体的实现步骤如下:
- 使用
BeanFactoryUtils.transformedBeanName(beanName)
将beanName转换为标准格式。 - 调用
resolveBeanClass(mbd, bdName)
方法,解析并设置Bean定义的类信息。 - 如果Bean定义中的isFactoryMethodUnique为true且factoryMethodToIntrospect为null,则使用ConstructorResolver来尝试解析工厂方法(factory method)。
- 创建一个BeanDefinitionHolder,根据beanName和mbd构造,如果beanName与bdName相等,则使用已存在的mergedBeanDefinitionHolders,否则创建一个新的BeanDefinitionHolder。
- 调用resolver的
isAutowireCandidate(holder, descriptor)
方法进行判断。 - 返回判断结果,表示该Bean是否应该被考虑作为自动装配候选。
java
protected boolean isAutowireCandidate(String beanName, RootBeanDefinition mbd,
DependencyDescriptor descriptor, AutowireCandidateResolver resolver) {
String bdName = BeanFactoryUtils.transformedBeanName(beanName);
resolveBeanClass(mbd, bdName);
if (mbd.isFactoryMethodUnique && mbd.factoryMethodToIntrospect == null) {
new ConstructorResolver(this).resolveFactoryMethodIfPossible(mbd);
}
BeanDefinitionHolder holder = (beanName.equals(bdName) ?
this.mergedBeanDefinitionHolders.computeIfAbsent(beanName,
key -> new BeanDefinitionHolder(mbd, beanName, getAliases(bdName))) :
new BeanDefinitionHolder(mbd, beanName, getAliases(bdName)));
return resolver.isAutowireCandidate(holder, descriptor);
}
getBeanDefinition(String beanName)
这个用于根据给定的beanName获取对应的Bean定义(BeanDefinition)对象 。
java
@Override
public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
BeanDefinition bd = this.beanDefinitionMap.get(beanName);
if (bd == null) {
if (logger.isTraceEnabled()) {
logger.trace("No bean named '" + beanName + "' found in " + this);
}
throw new NoSuchBeanDefinitionException(beanName);
}
return bd;
}
getBeanNamesIterator()
通过使用CompositeIterator,可以将多个迭代器组合成一个逻辑上的整体,方便遍历和访问各个迭代器的元素。这个方法的作用是将beanDefinitionNames和manualSingletonNames中的Bean定义名称合并为一个迭代器,以提供对所有Bean定义名称的统一访问。
java
@Override
public Iterator<String> getBeanNamesIterator() {
CompositeIterator<String> iterator = new CompositeIterator<>();
iterator.add(this.beanDefinitionNames.iterator());
iterator.add(this.manualSingletonNames.iterator());
return iterator;
}
clearMergedBeanDefinition(String beanName)
这个方法主要是用来清理与给定beanName相关的合并Bean定义信息和持有者。在Spring容器中,Bean定义信息可能存在于不同的地方,所以需要在清理时同时考虑清除相关的持有者。
java
@Override
protected void clearMergedBeanDefinition(String beanName) {
super.clearMergedBeanDefinition(beanName);
this.mergedBeanDefinitionHolders.remove(beanName);
}
clearMetadataCache()
这个方法主要用来清除所有与Bean元数据相关的缓存信息,包括合并Bean定义持有者和类型缓存。通过清空这些缓存,可以刷新和更新容器中的Bean定义和类型信息,使得后续的操作能够重新获取最新的元数据。
java
@Override
public void clearMetadataCache() {
super.clearMetadataCache();
this.mergedBeanDefinitionHolders.clear();
clearByTypeCache();
}
freezeConfiguration()
这个方法主要用于冻结容器的配置,即禁止对容器的配置进行修改。通过设置configurationFrozen为true,可以防止后续的配置修改,以保护已经完成的配置不受更改。同时,通过将beanDefinitionNames转换为字符串数组并保存在frozenBeanDefinitionNames中,可以记录当前的Bean定义名称,方便后续的使用和比较。
java
@Override
public void freezeConfiguration() {
this.configurationFrozen = true;
this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);
}
isBeanEligibleForMetadataCaching
这个方法用于确定指定的Bean是否符合元数据缓存的条件。如果容器的配置已被冻结,表示不会再有修改操作,此时所有的Bean都被认为是符合元数据缓存的条件的。如果容器的配置未被冻结,则会使用父类的默认判断逻辑来确定指定的Bean是否符合元数据缓存的条件。
java
/**
* Considers all beans as eligible for metadata caching
* if the factory's configuration has been marked as frozen.
* @see #freezeConfiguration()
*/
@Override
protected boolean isBeanEligibleForMetadataCaching(String beanName) {
return (this.configurationFrozen || super.isBeanEligibleForMetadataCaching(beanName));
}
preInstantiateSingletons()
这个方法的主要目的是提前实例化所有非懒加载的单例Bean,并在初始化完成后触发SmartInitializingSingleton的回调方法。通过预实例化单例Bean,在容器启动时可以避免在第一次使用时才进行实例化,为后续的Bean使用提供了便利性和性能优化。同时,也会触发SmartInitializingSingleton的回调,用于在所有单例Bean实例化完成后进行一些定制的初始化操作。
具体实现步骤如下:
- 如果日志级别为trace,记录关于预初始化单例Bean的日志信息。
- 创建一个副本的beanDefinitionNames列表,用于迭代预初始化单例Bean。这样做是为了防止在迭代过程中存在可能会注册新的bean定义的初始化方法。
- 遍历beanNames列表,获取每个bean定义,并判断是否为非抽象、单例且非懒加载的Bean。
- 如果是FactoryBean类型的Bean,先获取对应的FactoryBean实例,然后判断是否为SmartFactoryBean并判断是否需要立即初始化。如果需要立即初始化,则调用getBean(beanName)方法。
- 如果是普通的Bean,则直接调用getBean(beanName)方法进行初始化。
- 再次遍历beanNames列表,获取每个已实例化的单例Bean实例。
- 如果该Bean实例属于SmartInitializingSingleton类型,执行afterSingletonsInstantiated()方法来触发smart初始化回调。
java
@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(
(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
.tag("beanName", beanName);
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
smartInitialize.end();
}
}
}
registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
这个方法的主要目的是将给定的beanName和beanDefinition注册到beanDefinitionMap中。如果已存在相同名称的Bean定义,则根据配置决定是否允许覆盖,并进行相应的处理。如果不存在相同名称的Bean定义,则将其添加到beanDefinitionMap和beanDefinitionNames中,并对相应的集合进行更新操作。最后,根据情况重置Bean定义和清空类型缓存。
具体实现步骤如下:
- 检查beanName和beanDefinition是否为空,并进行相应的校验。
- 如果beanDefinition是AbstractBeanDefinition的实例,调用其validate()方法进行校验。
- 从beanDefinitionMap中获取名称为beanName的已存在的Bean定义。
- 如果已存在的Bean定义不为空,则根据配置决定是否允许Bean定义覆盖。如果不允许覆盖,则抛出BeanDefinitionOverrideException异常;如果允许覆盖且新的Bean定义的角色高于已存在的Bean定义的角色,则记录日志信息进行覆盖。
- 如果新的Bean定义与已存在的Bean定义不相等,则记录日志信息进行覆盖。
- 将新的Bean定义放入beanDefinitionMap中,如果已存在相同名称的Bean定义则进行替换。
- 如果已经开始创建Bean实例,则对beanDefinitionMap进行同步操作,以保证线程安全。
- 更新beanDefinitionNames列表,将新的beanName添加到末尾,并移除manualSingletonNames中的beanName。
- 如果还未开始创建Bean实例,则直接将新的beanName添加到beanDefinitionNames列表,并移除manualSingletonNames中的beanName。
- 重置frozenBeanDefinitionNames为null。
- 如果已存在相同名称的Bean定义或包含该名称的单例Bean实例,则重置该名称的Bean定义。
- 如果配置已被冻结,则清空类型缓存。
java
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}
else if (existingDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (logger.isInfoEnabled()) {
logger.info("Overriding user-defined bean definition for bean '" + beanName +
"' with a framework-generated bean definition: replacing [" +
existingDefinition + "] with [" + beanDefinition + "]");
}
}
else if (!beanDefinition.equals(existingDefinition)) {
if (logger.isDebugEnabled()) {
logger.debug("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
removeManualSingletonName(beanName);
}
}
else {
// Still in startup registration phase
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (existingDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
else if (isConfigurationFrozen()) {
clearByTypeCache();
}
}
removeBeanDefinition(String beanName)
这个方法的主要目的是从容器中移除指定名称的Bean定义。首先从beanDefinitionMap中移除,并更新beanDefinitionNames列表。如果容器已开始创建Bean实例,则需要进行同步操作,以确保删除操作的线程安全性。最后,重置被移除的Bean定义和frozenBeanDefinitionNames。
具体实现步骤如下:
- 检查beanName是否为空,并进行相应的校验。
- 从beanDefinitionMap中移除名称为beanName的Bean定义,并将其保存到bd变量中。
- 如果移除的Bean定义为null,则表示容器中不存在该beanName对应的Bean定义,抛出NoSuchBeanDefinitionException异常并记录日志。
- 如果已经开始创建Bean实例,则对beanDefinitionMap进行同步操作,以保证线程安全。
- 更新beanDefinitionNames列表,移除包含beanName的元素。
- 如果还未开始创建Bean实例,则直接从beanDefinitionNames列表中移除beanName。
- 重置frozenBeanDefinitionNames为null。
- 重置beanName对应的Bean定义。
java
@Override
public void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
Assert.hasText(beanName, "'beanName' must not be empty");
BeanDefinition bd = this.beanDefinitionMap.remove(beanName);
if (bd == null) {
if (logger.isTraceEnabled()) {
logger.trace("No bean named '" + beanName + "' found in " + this);
}
throw new NoSuchBeanDefinitionException(beanName);
}
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames);
updatedDefinitions.remove(beanName);
this.beanDefinitionNames = updatedDefinitions;
}
}
else {
// Still in startup registration phase
this.beanDefinitionNames.remove(beanName);
}
this.frozenBeanDefinitionNames = null;
resetBeanDefinition(beanName);
}
resetBeanDefinition(String beanName)
这个方法的主要目的是重置与给定beanName相关的bean定义及其相关的缓存。通过递归方式重置父bean定义和调用MergedBeanDefinitionPostProcessor的resetBeanDefinition方法来确保与给定bean相关的所有bean定义都被重置。这一过程包括移除合并的bean定义、销毁单例bean实例以及通知后处理器进行重置操作。通过调用resetBeanDefinition方法,可以确保在替换或删除bean定义后,与该bean相关的缓存得到正确的重置和清理。
具体实现步骤如下:
- 调用clearMergedBeanDefinition方法,移除已经创建的与给定beanName相关的合并的bean定义信息。
- 调用destroySingleton方法,销毁与给定beanName相关的单例bean实例。
- 遍历beanPostProcessorCache中mergedDefinition集合中的所有MergedBeanDefinitionPostProcessor对象,调用其resetBeanDefinition方法,通知它们指定的bean定义已被重置。
- 遍历beanDefinitionNames列表中的所有bean定义名称,检查是否有父bean名称与给定beanName相等。如果有,则递归地调用resetBeanDefinition方法来重置这些bean定义。
java
/**
* Reset all bean definition caches for the given bean,
* including the caches of beans that are derived from it.
* <p>Called after an existing bean definition has been replaced or removed,
* triggering {@link #clearMergedBeanDefinition}, {@link #destroySingleton}
* and {@link MergedBeanDefinitionPostProcessor#resetBeanDefinition} on the
* given bean and on all bean definitions that have the given bean as parent.
* @param beanName the name of the bean to reset
* @see #registerBeanDefinition
* @see #removeBeanDefinition
*/
protected void resetBeanDefinition(String beanName) {
// Remove the merged bean definition for the given bean, if already created.
clearMergedBeanDefinition(beanName);
// Remove corresponding bean from singleton cache, if any. Shouldn't usually
// be necessary, rather just meant for overriding a context's default beans
// (e.g. the default StaticMessageSource in a StaticApplicationContext).
destroySingleton(beanName);
// Notify all post-processors that the specified bean definition has been reset.
for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) {
processor.resetBeanDefinition(beanName);
}
// Reset all bean definitions that have the given bean as parent (recursively).
for (String bdName : this.beanDefinitionNames) {
if (!beanName.equals(bdName)) {
BeanDefinition bd = this.beanDefinitionMap.get(bdName);
// Ensure bd is non-null due to potential concurrent modification of beanDefinitionMap.
if (bd != null && beanName.equals(bd.getParentName())) {
resetBeanDefinition(bdName);
}
}
}
}
registerSingleton(String beanName, Object singletonObject)
这个方法的主要目的是在向容器注册单例对象时,除了进行基本的注册操作外,还会更新manualSingletonNames集合和清空类型缓存。通过更新manualSingletonNames集合,可以记录手动注册的单例对象的名称。而通过清空类型缓存,可以确保在获取Bean类型信息时能够获取最新的信息。
具体实现步骤如下:
- 调用super.registerSingleton方法,向父类注册单例对象。
- 调用updateManualSingletonNames方法,更新manualSingletonNames集合。
- 如果manualSingletonNames集合不存在beanName,则将其添加到集合中。
- 如果beanDefinitionMap不包含beanName对应的Bean定义,则返回true,表示需要更新manualSingletonNames集合。
- 调用clearByTypeCache方法,清空类型缓存。
java
@Override
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
super.registerSingleton(beanName, singletonObject);
updateManualSingletonNames(set -> set.add(beanName), set -> !this.beanDefinitionMap.containsKey(beanName));
clearByTypeCache();
}
destroySingletons()
这个方法的主要目的是在销毁所有的单例对象时,除了进行基本的销毁操作外,还会更新manualSingletonNames集合和清空类型缓存。通过更新manualSingletonNames集合,可以清空手动注册的单例对象的名称。而通过清空类型缓存,可以确保在获取Bean类型信息时能够获取最新的信息。
具体实现步骤如下:
- 调用super.destroySingletons方法,销毁所有的单例对象。
- 调用updateManualSingletonNames方法,更新manualSingletonNames集合。
- 调用Set::clear来清空manualSingletonNames集合。
- 如果manualSingletonNames集合不为空,则返回true,表示需要更新manualSingletonNames集合。
- 调用clearByTypeCache方法,清空类型缓存。
java
@Override
public void destroySingletons() {
super.destroySingletons();
updateManualSingletonNames(Set::clear, set -> !set.isEmpty());
clearByTypeCache();
updateManualSingletonNames(Consumer<Set<String>> action, Predicate<Set<String>> condition)
这个方法的作用是根据传入的操作函数和条件函数对manualSingletonNames集合进行更新。如果容器已经开始创建Bean实例,则在同步块内执行更新操作;如果还在启动注册阶段,则直接执行更新操作。这样可以确保更新操作的线程安全性,并根据需要对manualSingletonNames集合进行更新。
具体实现步骤如下:
- 先判断是否已经开始创建Bean实例,如果是则进行同步操作,以保证线程安全性。
- 判断condition函数是否满足对manualSingletonNames集合的条件。
- 如果满足条件,则执行action函数对manualSingletonNames集合进行操作更新。
- 最后将更新后的集合赋值给manualSingletonNames。
java
private void updateManualSingletonNames(Consumer<Set<String>> action, Predicate<Set<String>> condition) {
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
if (condition.test(this.manualSingletonNames)) {
Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
action.accept(updatedSingletons);
this.manualSingletonNames = updatedSingletons;
}
}
}
else {
// Still in startup registration phase
if (condition.test(this.manualSingletonNames)) {
action.accept(this.manualSingletonNames);
}
}
}
clearByTypeCache()
这个方法的主要用于清空类型缓存的操作,即清空allBeanNamesByType和singletonBeanNamesByType两个缓存集合。
java
/**
* Remove any assumptions about by-type mappings.
*/
private void clearByTypeCache() {
this.allBeanNamesByType.clear();
this.singletonBeanNamesByType.clear();
}
resolveNamedBean(Class<T> requiredType)
这个方法的主要目的是根据给定的requiredType解析获取对应的NamedBeanHolder。首先在当前Bean工厂中尝试解析,如果找到则直接返回结果。否则,会通过向上递归访问父Bean工厂来尝试解析该类型的Bean。如果最终无法解析到对应的Bean,则抛出异常。
具体实现步骤如下:
- 检查requiredType是否为空,为空则抛出IllegalArgumentException异常。
- 调用resolveNamedBean方法,根据requiredType解析获取对应的NamedBeanHolder。
- 如果返回的NamedBeanHolder不为空,直接返回该结果。
- 获取父Bean工厂(parent),如果它是一个AutowireCapableBeanFactory,则调用其resolveNamedBean方法继续解析。
- 如果父Bean工厂不是AutowireCapableBeanFactory类型,或者父Bean工厂也无法解析该类型的Bean,则抛出NoSuchBeanDefinitionException异常。
java
@Override
public <T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType) throws BeansException {
Assert.notNull(requiredType, "Required type must not be null");
NamedBeanHolder<T> namedBean = resolveNamedBean(ResolvableType.forRawClass(requiredType), null, false);
if (namedBean != null) {
return namedBean;
}
BeanFactory parent = getParentBeanFactory();
if (parent instanceof AutowireCapableBeanFactory) {
return ((AutowireCapableBeanFactory) parent).resolveNamedBean(requiredType);
}
throw new NoSuchBeanDefinitionException(requiredType);
}
resolveNamedBean(
ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull)
这个方法的作用是根据给定的requiredType解析并返回对应的NamedBeanHolder,其中包含了候选bean的名称和实例。它首先获取符合requiredType的候选bean的名称数组,然后根据候选bean的数量和属性判断来确定最终的候选bean。如果找到了唯一的候选bean,则直接返回结果;如果候选bean有多个并且nonUniqueAsNull为true,则返回null;如果候选bean有多个并且nonUniqueAsNull为false,则抛出异常。
具体实现步骤如下:
- 检查requiredType是否为空,为空则抛出IllegalArgumentException异常。
- 根据requiredType获取符合该类型的所有候选bean的名称数组candidateNames。
- 如果候选bean的数量大于1,则根据
isAutowireCandidate()
方法判断哪些候选bean可以作为自动装配的对象,将符合条件的候选bean名称保存到autowireCandidates列表中。 - 如果autowireCandidates列表不为空,则将列表转换为字符串数组,并重新赋值给candidateNames。
- 如果candidateNames只有一个元素,则直接调用resolveNamedBean方法解析该唯一的候选bean。
- 如果candidateNames有多个元素,则遍历candidateNames并针对每个候选bean,根据是否是存在单例实例和args是否为空来决定添加到candidates集合中的值。然后确定主要候选bean和优先级最高的候选bean。
- 如果找到了主要候选bean或者优先级最高的候选bean,则根据resolvedBeanInstance是否为空来判断返回结果。
- 如果nonUniqueAsNull为false,则抛出NoUniqueBeanDefinitionException异常表示没有唯一的候选bean。
java
@Nullable
private <T> NamedBeanHolder<T> resolveNamedBean(
ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) throws BeansException {
Assert.notNull(requiredType, "Required type must not be null");
String[] candidateNames = getBeanNamesForType(requiredType);
if (candidateNames.length > 1) {
List<String> autowireCandidates = new ArrayList<>(candidateNames.length);
for (String beanName : candidateNames) {
if (!containsBeanDefinition(beanName) || getBeanDefinition(beanName).isAutowireCandidate()) {
autowireCandidates.add(beanName);
}
}
if (!autowireCandidates.isEmpty()) {
candidateNames = StringUtils.toStringArray(autowireCandidates);
}
}
if (candidateNames.length == 1) {
return resolveNamedBean(candidateNames[0], requiredType, args);
}
else if (candidateNames.length > 1) {
Map<String, Object> candidates = CollectionUtils.newLinkedHashMap(candidateNames.length);
for (String beanName : candidateNames) {
if (containsSingleton(beanName) && args == null) {
Object beanInstance = getBean(beanName);
candidates.put(beanName, (beanInstance instanceof NullBean ? null : beanInstance));
}
else {
candidates.put(beanName, getType(beanName));
}
}
String candidateName = determinePrimaryCandidate(candidates, requiredType.toClass());
if (candidateName == null) {
candidateName = determineHighestPriorityCandidate(candidates, requiredType.toClass());
}
if (candidateName != null) {
Object beanInstance = candidates.get(candidateName);
if (beanInstance == null) {
return null;
}
if (beanInstance instanceof Class) {
return resolveNamedBean(candidateName, requiredType, args);
}
return new NamedBeanHolder<>(candidateName, (T) beanInstance);
}
if (!nonUniqueAsNull) {
throw new NoUniqueBeanDefinitionException(requiredType, candidates.keySet());
}
}
return null;
}
resolveNamedBean(
String beanName, ResolvableType requiredType, @Nullable Object[] args)
这个方法的作用是根据给定的beanName解析并返回对应的NamedBeanHolder。它通过调用getBean方法获取指定beanName的bean实例,并判断是否为NullBean。然后使用adaptBeanInstance方法将bean实例适配为requiredType对应的类型。最后创建一个NamedBeanHolder对象,并将beanName和适配后的bean实例作为参数构造该对象,并返回。
具体实现步骤如下:
- 调用getBean方法获取指定beanName的bean实例,并传入null和args参数。
- 检查bean对象是否是NullBean类型,如果是则返回null。
- 调用adaptBeanInstance方法,将获取到的bean实例适配为requiredType对应的类型。
- 创建一个NamedBeanHolder对象,将beanName和适配后的bean实例作为参数传入。
- 返回NamedBeanHolder对象。
java
@Nullable
private <T> NamedBeanHolder<T> resolveNamedBean(
String beanName, ResolvableType requiredType, @Nullable Object[] args) throws BeansException {
Object bean = getBean(beanName, null, args);
if (bean instanceof NullBean) {
return null;
}
return new NamedBeanHolder<T>(beanName, adaptBeanInstance(beanName, bean, requiredType.toClass()));
}
resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter)
这个方法的主要目的是根据DependencyDescriptor描述符解析依赖项。根据不同的依赖类型(如Optional、ObjectFactory、ObjectProvider等),采取相应的解析策略返回结果。如果需要延迟解析,则尝试获取延迟解析的代理对象;否则,调用doResolveDependency方法进行实际的解析操作。最终返回解析的结果。
具体实现步骤如下:
- 调用descriptor的initParameterNameDiscovery方法,初始化参数名称发现器。
- 检查dependencyType是否为Optional类型,如果是则调用createOptionalDependency方法创建Optional类型的依赖关系并返回。
- 检查dependencyType是否为ObjectFactory或ObjectProvider类型,如果是则创建DependencyObjectProvider对象作为依赖关系的解析结果,并返回。
- 检查dependencyType是否为javaxInjectProviderClass定义的类型,如果是则使用Jsr330Factory创建相应的DependencyProvider对象作为依赖关系的解析结果,并返回。
- 如果上述条件都不满足,调用getAutowireCandidateResolver的getLazyResolutionProxyIfNecessary方法尝试获取延迟解析的代理对象result。
- 如果result为null,则调用doResolveDependency方法进行真正的依赖解析。
- 返回解析结果result。
java
@Override
@Nullable
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
if (Optional.class == descriptor.getDependencyType()) {
return createOptionalDependency(descriptor, requestingBeanName);
}
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
}
else {
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter)
这个方法的主要目的是根据给定的DependencyDescriptor描述符解析依赖项。它会尝试从不同的途径解析依赖,包括解析缩写形式、解析建议值、解析多个候选bean、寻找匹配候选bean,并进行相应的处理和转换。最终返回解析的结果。
具体实现步骤如下:
- 调用ConstructorResolver的setCurrentInjectionPoint方法,将当前的依赖描述符设为当前的注入点(用于支持构造函数的循环依赖)。
- 调用descriptor的resolveShortcut方法,尝试解析依赖的缩写形式。如果缩写形式存在,则返回相应的结果。
- 获取依赖的类型和建议值,并判断是否有建议值。如果有建议值,进行相应的解析和转换操作。
- 调用resolveMultipleBeans方法尝试解析多个候选bean。
- 调用findAutowireCandidates方法找到符合条件的候选bean,并保存到matchingBeans集合中。
- 如果matchingBeans为空,根据IsRequired方法判断是否必须要找到匹配的bean。如果是必需的,抛出异常;否则返回null。
- 如果matchingBeans的大小大于1,根据determineAutowireCandidate方法确定最适合的候选bean,如果没有找到唯一的候选bean,则根据isRequired判断是否需要抛出异常;如果是可选的集合或映射类型,则返回null。
- 如果matchingBeans的大小等于1,说明找到了唯一的候选bean,将该候选bean和对应的bean名称保存到autowiredBeanNames集合中。
- 如果instanceCandidate是Class类型,调用descriptor的resolveCandidate方法解析该候选bean的实例。
- 将结果保存到result中,并进行必要的处理:如果result是NullBean类型并且isRequired为true,则抛出异常;如果result不是目标类型的实例,则抛出异常。
- 返回解析的结果result。
java
@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
Class<?> type = descriptor.getDependencyType();
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
if (value instanceof String) {
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ?
getMergedBeanDefinition(beanName) : null);
value = evaluateBeanDefinitionString(strVal, bd);
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
try {
return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
}
catch (UnsupportedOperationException ex) {
// A custom TypeConverter which does not support TypeDescriptor resolution...
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
}
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
if (matchingBeans.size() > 1) {
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
}
else {
// In case of an optional Collection/Map, silently ignore a non-unique case:
// possibly it was meant to be an empty collection of multiple regular beans
// (before 4.3 in particular when we didn't even look for collection beans).
return null;
}
}
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
else {
// We have exactly one match.
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
if (instanceCandidate instanceof Class) {
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
Object result = instanceCandidate;
if (result instanceof NullBean) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
result = null;
}
if (!ClassUtils.isAssignableValue(type, result)) {
throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
}
return result;
}
finally {
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}
resolveMultipleBeans(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter)
这个方法的主要目的是根据给定的DependencyDescriptor描述符解析多个依赖项。根据不同的依赖类型(Stream、数组、集合、Map),采取相应的解析策略并返回结果。最终返回解析的结果。
具体实现步骤如下:
- 获取依赖的类型。
- 如果Descriptor是StreamDependencyDescriptor类型的,则通过调用findAutowireCandidates方法找到所有匹配的候选bean,并根据排序逻辑返回一个Stream对象。
- 如果类型是数组类型,则获取数组元素类型和参数化的ResolvableType,并根据数组元素类型从候选bean中找到匹配的候选bean,并返回一个数组。
- 如果类型是Collection接口并且是一个接口类型,则获取集合元素的类型,然后根据该元素类型从候选bean中找到匹配的候选bean,并返回一个集合。
- 如果类型是Map类型,则获取Map键的类型,如果键的类型不是String类型,则返回null。然后根据值的类型从候选bean中找到匹配的候选bean,并返回一个Map对象。
- 如果上述条件都不满足,则返回null。
java
@Nullable
private Object resolveMultipleBeans(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) {
Class<?> type = descriptor.getDependencyType();
if (descriptor instanceof StreamDependencyDescriptor) {
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
Stream<Object> stream = matchingBeans.keySet().stream()
.map(name -> descriptor.resolveCandidate(name, type, this))
.filter(bean -> !(bean instanceof NullBean));
if (((StreamDependencyDescriptor) descriptor).isOrdered()) {
stream = stream.sorted(adaptOrderComparator(matchingBeans));
}
return stream;
}
else if (type.isArray()) {
Class<?> componentType = type.getComponentType();
ResolvableType resolvableType = descriptor.getResolvableType();
Class<?> resolvedArrayType = resolvableType.resolve(type);
if (resolvedArrayType != type) {
componentType = resolvableType.getComponentType().resolve();
}
if (componentType == null) {
return null;
}
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType,
new MultiElementDescriptor(descriptor));
if (matchingBeans.isEmpty()) {
return null;
}
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
Object result = converter.convertIfNecessary(matchingBeans.values(), resolvedArrayType);
if (result instanceof Object[]) {
Comparator<Object> comparator = adaptDependencyComparator(matchingBeans);
if (comparator != null) {
Arrays.sort((Object[]) result, comparator);
}
}
return result;
}
else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
Class<?> elementType = descriptor.getResolvableType().asCollection().resolveGeneric();
if (elementType == null) {
return null;
}
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType,
new MultiElementDescriptor(descriptor));
if (matchingBeans.isEmpty()) {
return null;
}
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
Object result = converter.convertIfNecessary(matchingBeans.values(), type);
if (result instanceof List) {
if (((List<?>) result).size() > 1) {
Comparator<Object> comparator = adaptDependencyComparator(matchingBeans);
if (comparator != null) {
((List<?>) result).sort(comparator);
}
}
}
return result;
}
else if (Map.class == type) {
ResolvableType mapType = descriptor.getResolvableType().asMap();
Class<?> keyType = mapType.resolveGeneric(0);
if (String.class != keyType) {
return null;
}
Class<?> valueType = mapType.resolveGeneric(1);
if (valueType == null) {
return null;
}
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType,
new MultiElementDescriptor(descriptor));
if (matchingBeans.isEmpty()) {
return null;
}
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
return matchingBeans;
}
else {
return null;
}
}
indicatesMultipleBeans(Class<?> type)
这个方法的主要目的是判断给定的类型是否表示多个bean。如果类型是数组类型,或者是集合类型(接口类型且是Collection的子类)或Map类型(接口类型且是Map的子类),则认为该类型表示多个bean,返回true;否则返回false。
java
private boolean indicatesMultipleBeans(Class<?> type) {
return (type.isArray() || (type.isInterface() &&
(Collection.class.isAssignableFrom(type) || Map.class.isAssignableFrom(type))));
}
adaptDependencyComparator(Map<String, ?> matchingBeans)
这个方法的主要目的是适配依赖比较器。它会根据当前容器中的依赖比较器类型进行相应的适配处理。如果依赖比较器是OrderComparator的实例,则使用createFactoryAwareOrderSourceProvider方法创建一个FactoryAwareOrderSourceProvider对象,并传递给OrderComparator的withSourceProvider方法。最终返回适配后的依赖比较器。如果依赖比较器不是OrderComparator的实例,则直接返回原始的依赖比较器。
具体实现步骤如下:
- 获取当前容器中的依赖比较器comparator。
- 如果comparator是OrderComparator的实例,则调用withSourceProvider方法,将createFactoryAwareOrderSourceProvider方法创建的FactoryAwareOrderSourceProvider对象作为参数传递给它。
- 否则,直接返回comparator。
java
@Nullable
private Comparator<Object> adaptDependencyComparator(Map<String, ?> matchingBeans) {
Comparator<Object> comparator = getDependencyComparator();
if (comparator instanceof OrderComparator) {
return ((OrderComparator) comparator).withSourceProvider(
createFactoryAwareOrderSourceProvider(matchingBeans));
}
else {
return comparator;
}
}
adaptOrderComparator(Map<String, ?> matchingBeans)
这个方法的主要目的是适配顺序比较器。它会根据当前容器中的依赖比较器类型进行相应的适配处理。如果依赖比较器是OrderComparator的实例,则将其作为comparator;否则,使用OrderComparator.INSTANCE作为comparator。然后,通过调用createFactoryAwareOrderSourceProvider方法创建一个FactoryAwareOrderSourceProvider对象,并将matchingBeans作为参数传递给它。最后,调用comparator的withSourceProvider方法,将FactoryAwareOrderSourceProvider对象作为参数传递给它。返回适配后的依赖比较器。
具体实现步骤如下:
- 获取当前容器中的依赖比较器dependencyComparator。
- 如果dependencyComparator是OrderComparator的实例,则将其强制转换为OrderComparator类型,并赋值给comparator。
- 否则,使用OrderComparator.INSTANCE作为comparator的值。
- 调用createFactoryAwareOrderSourceProvider方法创建一个FactoryAwareOrderSourceProvider对象,并将matchingBeans作为参数传递给它。
- 调用comparator的withSourceProvider方法,将上一步创建的FactoryAwareOrderSourceProvider对象作为参数传递给它。
- 返回适配后的依赖比较器。
java
private Comparator<Object> adaptOrderComparator(Map<String, ?> matchingBeans) {
Comparator<Object> dependencyComparator = getDependencyComparator();
OrderComparator comparator = (dependencyComparator instanceof OrderComparator ?
(OrderComparator) dependencyComparator : OrderComparator.INSTANCE);
return comparator.withSourceProvider(createFactoryAwareOrderSourceProvider(matchingBeans));
}
createFactoryAwareOrderSourceProvider(Map<String, ?> beans)
这个方法的主要目的是创建一个FactoryAwareOrderSourceProvider对象。它会根据给定的beans创建一个映射关系,将实例和对应的bean名称存储起来,并使用这个映射关系创建一个FactoryAwareOrderSourceProvider对象。最后返回创建的FactoryAwareOrderSourceProvider对象。
具体实现步骤如下:
- 创建一个IdentityHashMap对象instancesToBeanNames存储实例与bean名称的映射关系。
- 遍历beans中的每个键值对,将实例instance作为键,bean名称beanName作为值,添加到instancesToBeanNames中。
- 创建一个FactoryAwareOrderSourceProvider对象,并将instancesToBeanNames作为参数传递给它。
- 返回创建的FactoryAwareOrderSourceProvider对象。
java
private OrderComparator.OrderSourceProvider createFactoryAwareOrderSourceProvider(Map<String, ?> beans) {
IdentityHashMap<Object, String> instancesToBeanNames = new IdentityHashMap<>();
beans.forEach((beanName, instance) -> instancesToBeanNames.put(instance, beanName));
return new FactoryAwareOrderSourceProvider(instancesToBeanNames);
}
findAutowireCandidates(
@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor)
这个方法的主要目的是查找符合所需类型的候选bean。它通过获取所有的候选bean名称,然后逐个判断是否满足自引用、自动装配等条件来确定最终的候选bean列表。最终返回一个Map对象,其中包含了匹配的候选bean名称和实例的映射。
具体实现步骤如下:
- 调用BeanFactoryUtils的beanNamesForTypeIncludingAncestors方法,根据requiredType查找所有匹配的候选bean名称。
- 创建一个空的LinkedHashMap对象result,用于存储匹配的候选bean名称和实例的映射。
- 遍历resolvableDependencies字段中的每个键值对,用来处理通过#addResolvableDependency方法设置的可解析的依赖项。如果当前autowiringType是requiredType的父类或接口,则将其值作为候选bean实例加入到result中。
- 遍历candidateNames中的每个候选bean名称,判断是否是自引用的候选bean,以及是否是符合自动装配的候选bean,如果是则调用#addCandidateEntry方法将候选bean添加到result中。
- 如果result仍然为空,表示没有找到符合要求的候选bean,则考虑使用fallback机制。
- 构造一个fallbackDescriptor,用于处理fallback情况下的依赖解析。
- 遍历candidateNames中的每个候选bean名称,判断是否满足fallback条件,并且是否有合适的限定符(如果有多个候选bean)。
- 如果满足条件,则调用#addCandidateEntry方法将候选bean添加到result中。
- 如果result仍然为空,并且requiredType不表示多个bean,最后尝试自引用的情况(即bean依赖自身)。
- 遍历candidateNames中的每个候选bean名称,判断是否是自引用的候选bean,并且不是依赖集合中的同一个bean本身。
- 如果满足条件,则调用#addCandidateEntry方法将候选bean添加到result中。
- 返回结果result,即匹配的候选bean名称和实例的映射。
java
protected Map<String, Object> findAutowireCandidates(
@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
Map<String, Object> result = CollectionUtils.newLinkedHashMap(candidateNames.length);
for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
Class<?> autowiringType = classObjectEntry.getKey();
if (autowiringType.isAssignableFrom(requiredType)) {
Object autowiringValue = classObjectEntry.getValue();
autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
if (requiredType.isInstance(autowiringValue)) {
result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
break;
}
}
}
for (String candidate : candidateNames) {
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
if (result.isEmpty()) {
boolean multiple = indicatesMultipleBeans(requiredType);
// Consider fallback matches if the first pass failed to find anything...
DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
for (String candidate : candidateNames) {
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor) &&
(!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
if (result.isEmpty() && !multiple) {
// Consider self references as a final pass...
// but in the case of a dependency collection, not the very same bean itself.
for (String candidate : candidateNames) {
if (isSelfReference(beanName, candidate) &&
(!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&
isAutowireCandidate(candidate, fallbackDescriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
}
}
return result;
}
addCandidateEntry(Map<String, Object> candidates, String candidateName,
DependencyDescriptor descriptor, Class<?> requiredType)
该方法的主要作用是将候选bean添加到候选对象映射candidates中。如果依赖描述符是MultiElementDescriptor类型,表示对集合类型的依赖进行解析;如果是单例或有序的流式依赖描述符,则解析候选bean实例并添加到candidates中;否则,直接将候选bean的类型存储在candidates中。
具体实现步骤如下:
- 判断依赖描述符descriptor是否是MultiElementDescriptor的实例。如果是,则表示对集合类型的依赖进行解析。
- 如果是MultiElementDescriptor, 则调用resolveCandidate方法解析候选bean,将结果存储在beanInstance中。
- 如果beanInstance不是NullBean的实例,则将候选bean实例存储在candidates中。
- 否则,判断候选bean是否为单例或者是StreamDependencyDescriptor的实例且是有序的。
- 如果是单例或有序的流式依赖描述符,则同样调用resolveCandidate方法解析候选bean,并将结果存储在beanInstance中。
- 如果beanInstance不是NullBean的实例,则将候选bean实例存储在candidates中。
- 否则,将候选bean的类型存储在candidates中。
determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor)
该方法的主要目的是确定自动装配的候选bean。它首先尝试找到首选的候选bean(通过determinePrimaryCandidate方法),如果找到则返回。如果没有找到首选的候选bean,则尝试找到优先级最高的候选bean(通过determineHighestPriorityCandidate方法),如果找到则返回。如果以上两个步骤都没有找到合适的候选bean,则根据一些条件选择后备候选bean。最终返回确定的候选bean的名称,如果没有找到则返回null。
具体实现步骤如下:
- 获取依赖描述符descriptor的所需类型requiredType。
- 调用determinePrimaryCandidate方法,根据requiredType从candidates中确定首选候选bean的名称primaryCandidate。
- 如果primaryCandidate不为null,则返回primaryCandidate。
- 否则,调用determineHighestPriorityCandidate方法,根据requiredType从candidates中确定优先级最高的候选bean的名称priorityCandidate。
- 如果priorityCandidate不为null,则返回priorityCandidate。
- 如果以上两个步骤都没有找到合适的候选bean,则进行后备处理。
- 遍历candidates中的每个候选bean的条目。
- 判断候选bean实例是否不为null并且是否存在于resolvableDependencies字段中,或者候选bean的名称与依赖名称匹配。
- 如果满足上述条件,则返回候选bean的名称。
- 如果以上步骤都没有找到合适的候选bean,则返回null。
java
@Nullable
protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
Class<?> requiredType = descriptor.getDependencyType();
String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
if (primaryCandidate != null) {
return primaryCandidate;
}
String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
if (priorityCandidate != null) {
return priorityCandidate;
}
// Fallback
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
String candidateName = entry.getKey();
Object beanInstance = entry.getValue();
if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||
matchesBeanName(candidateName, descriptor.getDependencyName())) {
return candidateName;
}
}
return null;
}
determinePrimaryCandidate(Map<String, Object> candidates, Class<?> requiredType)
该方法的主要目的是确定首选候选bean。它遍历候选bean的映射,通过调用isPrimary方法判断候选bean是否为首选候选bean。如果找到多个首选候选bean,则根据情况抛出异常或选择其中一个作为首选候选bean。最终返回首选候选bean的名称,如果没有找到首选候选bean则返回null。
具体实现步骤如下:
- 初始化primaryBeanName为null,用于存储找到的首选候选bean的名称。
- 遍历candidates中的每个候选bean的条目。
- 获取候选bean的名称candidateBeanName和实例beanInstance。
- 调用isPrimary方法,判断候选bean是否为首选候选bean。
- 如果是首选候选bean,则根据以下逻辑进行处理:
- 如果primaryBeanName已经不为null,则表示已经存在一个首选候选bean。
- 如果candidateBeanName和primaryBeanName都有对应的本地bean定义,则抛出NoUniqueBeanDefinitionException异常,表明在候选列表中找到了多个首选bean。
- 如果只有candidateBeanName有对应的本地bean定义,则将candidateBeanName赋值给primaryBeanName。
- 否则,将candidateBeanName赋值给primaryBeanName。
- 如果primaryBeanName已经不为null,则表示已经存在一个首选候选bean。
- 返回primaryBeanName,表示找到的首选候选bean的名称。如果没有找到首选候选bean,则返回null。
java
@Nullable
protected String determinePrimaryCandidate(Map<String, Object> candidates, Class<?> requiredType) {
String primaryBeanName = null;
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
String candidateBeanName = entry.getKey();
Object beanInstance = entry.getValue();
if (isPrimary(candidateBeanName, beanInstance)) {
if (primaryBeanName != null) {
boolean candidateLocal = containsBeanDefinition(candidateBeanName);
boolean primaryLocal = containsBeanDefinition(primaryBeanName);
if (candidateLocal && primaryLocal) {
throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(),
"more than one 'primary' bean found among candidates: " + candidates.keySet());
}
else if (candidateLocal) {
primaryBeanName = candidateBeanName;
}
}
else {
primaryBeanName = candidateBeanName;
}
}
}
return primaryBeanName;
}
determineHighestPriorityCandidate(Map<String, Object> candidates, Class<?> requiredType)
该方法的主要目的是确定优先级最高的候选bean。它遍历候选bean的映射,通过调用getPriority方法获取候选bean的优先级。如果找到多个具有相同优先级的候选bean,则抛出异常。如果找到优先级更高的候选bean,则更新最高优先级的候选bean的名称和优先级。最终返回优先级最高的候选bean的名称,如果没有找到则返回null。
具体实现步骤如下:
- 初始化highestPriorityBeanName和highestPriority为null,用于存储找到的优先级最高的候选bean的名称和优先级。
- 遍历candidates中的每个候选bean的条目。
- 获取候选bean的名称candidateBeanName和实例beanInstance。
- 判断beanInstance是否为null,如果为null则跳过。
- 调用getPriority方法,获取候选bean的优先级candidatePriority。
- 如果candidatePriority不为null,则根据以下逻辑进行处理:
- 如果highestPriorityBeanName已经不为null,则表示已经存在一个优先级最高的候选bean。
- 如果candidatePriority与highestPriority相等,则抛出NoUniqueBeanDefinitionException异常,表示在候选列表中找到多个具有相同优先级的bean。
- 如果candidatePriority小于highestPriority,则将candidateBeanName和candidatePriority更新为最高优先级的候选bean。
- 否则,将candidateBeanName和candidatePriority赋值给highestPriorityBeanName和highestPriority。
- 如果highestPriorityBeanName已经不为null,则表示已经存在一个优先级最高的候选bean。
- 返回highestPriorityBeanName,表示找到的优先级最高的候选bean的名称。如果没有找到优先级最高的候选bean,则返回null。
java
@Nullable
protected String determineHighestPriorityCandidate(Map<String, Object> candidates, Class<?> requiredType) {
String highestPriorityBeanName = null;
Integer highestPriority = null;
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
String candidateBeanName = entry.getKey();
Object beanInstance = entry.getValue();
if (beanInstance != null) {
Integer candidatePriority = getPriority(beanInstance);
if (candidatePriority != null) {
if (highestPriorityBeanName != null) {
if (candidatePriority.equals(highestPriority)) {
throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(),
"Multiple beans found with the same priority ('" + highestPriority +
"') among candidates: " + candidates.keySet());
}
else if (candidatePriority < highestPriority) {
highestPriorityBeanName = candidateBeanName;
highestPriority = candidatePriority;
}
}
else {
highestPriorityBeanName = candidateBeanName;
highestPriority = candidatePriority;
}
}
}
}
return highestPriorityBeanName;
}
isPrimary(String beanName, Object beanInstance)
该方法的主要作用是判断给定的bean是否为首选候选bean。它在本地bean定义中查找是否存在首选候选bean,并在父BeanFactory中进行递归判断。如果有任何一个条件满足,则返回true;否则返回false。
具体实现步骤如下:
- 调用transformedBeanName方法,将beanName转换为规范化的bean名称transformedBeanName。
- 调用containsBeanDefinition方法,判断是否包含transformedBeanName对应的本地bean定义。
- 如果包含该本地bean定义,则调用getMergedLocalBeanDefinition方法获取合并的本地bean定义,并调用isPrimary方法判断是否为首选候选bean。
- 如果getParentBeanFactory返回的对象是DefaultListableBeanFactory类型,则判断该父BeanFactory中是否有transformedBeanName和beanInstance对应的首选候选bean。
- 如果有,则返回true。
- 如果以上条件都不满足,则返回false。
java
protected boolean isPrimary(String beanName, Object beanInstance) {
String transformedBeanName = transformedBeanName(beanName);
if (containsBeanDefinition(transformedBeanName)) {
return getMergedLocalBeanDefinition(transformedBeanName).isPrimary();
}
BeanFactory parent = getParentBeanFactory();
return (parent instanceof DefaultListableBeanFactory &&
((DefaultListableBeanFactory) parent).isPrimary(transformedBeanName, beanInstance));
}
getPriority(Object beanInstance)
该方法的主要作用是获取bean的优先级。它首先获取依赖比较器,然后通过调用依赖比较器的getPriority方法,传入beanInstance作为参数,以获取bean的优先级。如果依赖比较器不是OrderComparator的实例,则返回null表示没有定义优先级。
具体实现步骤如下:
- 调用getDependencyComparator方法,获取依赖比较器comparator。
- 如果依赖比较器是OrderComparator的实例,则调用OrderComparator的getPriority方法,传入beanInstance参数,以获取bean的优先级。
- 如果依赖比较器不是OrderComparator的实例,则返回null。
java
@Nullable
protected Integer getPriority(Object beanInstance) {
Comparator<Object> comparator = getDependencyComparator();
if (comparator instanceof OrderComparator) {
return ((OrderComparator) comparator).getPriority(beanInstance);
}
return null;
}
isSelfReference(@Nullable String beanName, @Nullable String candidateName)
该方法的主要目的是判断给定的bean是否存在自引用。它检查beanName和candidateName是否都不为null,以及beanName与candidateName是否相等。如果两者相等,则表示存在自引用。否则,它会检查candidateName在容器中是否有对应的bean定义,并获取该定义中的工厂bean名字。如果工厂bean名字与beanName相等,则也表示存在自引用。最终返回true表示存在自引用,否则返回false。
具体实现步骤如下:
- 通过判断beanName和candidateName是否为null,以及beanName与candidateName是否相等来确定是否存在自引用。
- 如果beanName和candidateName都不为null,并且beanName与candidateName相等,则表示存在自引用。
- 否则,判断候选bean名字在容器中是否有对应的bean定义,以及该定义中的工厂bean名字是否与beanName相等。如果满足条件,则表示存在自引用。
java
/**
* Determine whether the given beanName/candidateName pair indicates a self reference,
* i.e. whether the candidate points back to the original bean or to a factory method
* on the original bean.
*/
private boolean isSelfReference(@Nullable String beanName, @Nullable String candidateName) {
return (beanName != null && candidateName != null &&
(beanName.equals(candidateName) || (containsBeanDefinition(candidateName) &&
beanName.equals(getMergedLocalBeanDefinition(candidateName).getFactoryBeanName()))));
}
checkBeanNotOfRequiredType(Class<?> type, DependencyDescriptor descriptor)
该方法的主要目的是检查bean是否与所需类型不匹配。它遍历所有的bean定义,获取每个bean的合并本地bean定义,并判断类型是否符合要求。如果发现不匹配的情况,则抛出BeanNotOfRequiredTypeException异常。另外,还会检查父BeanFactory是否是DefaultListableBeanFactory类型,并在这种情况下递归调用checkBeanNotOfRequiredType方法进行检查。
具体实现步骤如下:
- 遍历所有的bean定义名称,对每个bean进行检查。
- 获取合并的本地bean定义RootBeanDefinition。
- 获取目标类型targetType,并判断type是否是targetType的父类或接口。
- 调用isAutowireCandidate方法判断bean是否符合自动装配候选的条件。
- 如果满足上述条件,则可能是由于代理对象影响了目标类型匹配,抛出BeanNotOfRequiredTypeException异常。异常消息中包含beanName、type和beanType等信息。
- 如果在迭代过程中,发现NoSuchBeanDefinitionException异常,表示bean定义在迭代时被移除,则忽略该异常。
- 检查父BeanFactory是否是DefaultListableBeanFactory类型,如果是,则递归调用checkBeanNotOfRequiredType方法进行检查。
java
/**
* Raise a BeanNotOfRequiredTypeException for an unresolvable dependency, if applicable,
* i.e. if the target type of the bean would match but an exposed proxy doesn't.
*/
private void checkBeanNotOfRequiredType(Class<?> type, DependencyDescriptor descriptor) {
for (String beanName : this.beanDefinitionNames) {
try {
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
Class<?> targetType = mbd.getTargetType();
if (targetType != null && type.isAssignableFrom(targetType) &&
isAutowireCandidate(beanName, mbd, descriptor, getAutowireCandidateResolver())) {
// Probably a proxy interfering with target type match -> throw meaningful exception.
Object beanInstance = getSingleton(beanName, false);
Class<?> beanType = (beanInstance != null && beanInstance.getClass() != NullBean.class ?
beanInstance.getClass() : predictBeanType(beanName, mbd));
if (beanType != null && !type.isAssignableFrom(beanType)) {
throw new BeanNotOfRequiredTypeException(beanName, type, beanType);
}
}
}
catch (NoSuchBeanDefinitionException ex) {
// Bean definition got removed while we were iterating -> ignore.
}
}
BeanFactory parent = getParentBeanFactory();
if (parent instanceof DefaultListableBeanFactory) {
((DefaultListableBeanFactory) parent).checkBeanNotOfRequiredType(type, descriptor);
}
}
Optional<?> createOptionalDependency(
DependencyDescriptor descriptor, @Nullable String beanName, final Object... args)
该方法的主要目的是创建一个Optional类型的依赖项。它首先创建一个NestedDependencyDescriptor对象,并重写其中的isRequired方法和resolveCandidate方法,以支持非必需的依赖项和通过带有参数的getBean方法获取候选bean。然后,调用doResolveDependency方法进行依赖项的解析,并将结果包装成Optional对象返回。
具体实现步骤如下:
- 创建一个NestedDependencyDescriptor对象descriptorToUse,继承自DependencyDescriptor类,并重写其中的isRequired方法和resolveCandidate方法。
- isRequired方法返回false,表示依赖项不是必需的。
- resolveCandidate方法在解析候选bean时,判断args参数是否为空,如果不为空,则通过beanFactory.getBean方法使用参数args获取bean;否则递归调用父类的resolveCandidate方法进行正常的候选bean解析。
- 调用doResolveDependency方法,传入descriptorToUse、beanName、null和null作为参数,解析依赖项并获取结果。
- 如果结果是Optional类型,则直接返回结果。
- 否则,通过Optional.ofNullable方法将结果包装成Optional对象,并返回。
java
/**
* Create an {@link Optional} wrapper for the specified dependency.
*/
private Optional<?> createOptionalDependency(
DependencyDescriptor descriptor, @Nullable String beanName, final Object... args) {
DependencyDescriptor descriptorToUse = new NestedDependencyDescriptor(descriptor) {
@Override
public boolean isRequired() {
return false;
}
@Override
public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory) {
return (!ObjectUtils.isEmpty(args) ? beanFactory.getBean(beanName, args) :
super.resolveCandidate(beanName, requiredType, beanFactory));
}
};
Object result = doResolveDependency(descriptorToUse, beanName, null, null);
return (result instanceof Optional ? (Optional<?>) result : Optional.ofNullable(result));
}
toString()
该方法的主要目的是生成BeanFactory对象的字符串描述。它会将BeanFactory的标识、定义的bean名称列表和父BeanFactory的信息组装到一个字符串中,并返回该字符串作为对象的描述。描述包括BeanFactory对象的标识、定义的bean名称列表以及是否有父BeanFactory。如果有父BeanFactory,则还会显示父BeanFactory的标识。
java
@Override
public String toString() {
StringBuilder sb = new StringBuilder(ObjectUtils.identityToString(this));
sb.append(": defining beans [");
sb.append(StringUtils.collectionToCommaDelimitedString(this.beanDefinitionNames));
sb.append("]; ");
BeanFactory parent = getParentBeanFactory();
if (parent == null) {
sb.append("root of factory hierarchy");
}
else {
sb.append("parent: ").append(ObjectUtils.identityToString(parent));
}
return sb.toString();
}
readObject(ObjectInputStream ois)
该方法的目的是阻止DefaultListableBeanFactory对象被序列化。它通过抛出NotSerializableException异常来确保DefaultListableBeanFactory对象不能被序列化,同时提醒用户只能序列化SerializedBeanFactoryReference对象。
java
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
throw new NotSerializableException("DefaultListableBeanFactory itself is not deserializable - " +
"just a SerializedBeanFactoryReference is");
}
writeReplace()
该方法的主要目的是在序列化DefaultListableBeanFactory对象时进行替换。它根据是否设置了serializationId属性,决定是返回SerializedBeanFactoryReference对象,还是抛出NotSerializableException异常。如果设置了serializationId属性,则创建SerializedBeanFactoryReference对象进行替换,以保证序列化和反序列化的兼容性;如果没有设置serializationId属性,则抛出异常以阻止DefaultListableBeanFactory对象的序列化。
java
protected Object writeReplace() throws ObjectStreamException {
if (this.serializationId != null) {
return new SerializedBeanFactoryReference(this.serializationId);
}
else {
throw new NotSerializableException("DefaultListableBeanFactory has no serialization id");
}
}
SerializedBeanFactoryReference
SerializedBeanFactoryReference类是对DefaultListableBeanFactory对象的序列化引用,它存储了DefaultListableBeanFactory对象的最小化id引用。在反序列化过程中,这个最小化id引用会被解析为实际的DefaultListableBeanFactory实例。
通过使用SerializedBeanFactoryReference作为DefaultListableBeanFactory对象的序列化引用,可以避免直接序列化DefaultListableBeanFactory对象而带来的一些问题,同时仍然可以在反序列化时正确地重新构建DefaultListableBeanFactory实例。
SerializedBeanFactoryReference类的主要目的是提供对DefaultListableBeanFactory对象的序列化和反序列化支持。在反序列化过程中,由于DefaultListableBeanFactory对象可能已经不存在或被垃圾回收,SerializedBeanFactoryReference会优先尝试获取缓存中的DefaultListableBeanFactory实例。如果缓存中的实例不存在或已被回收,则使用一个虚拟的DefaultListableBeanFactory实例作为替代值,以保证反序列化过程能够成功进行。
具体实现步骤如下:
- SerializedBeanFactoryReference类实现了Serializable接口,表示该类可以被序列化。
- SerializedBeanFactoryReference类有一个id字段,用于存储DefaultListableBeanFactory对象的最小化id引用。
- SerializedBeanFactoryReference类有一个构造方法,接受一个id参数用于初始化id字段。
- SerializedBeanFactoryReference类还有一个私有方法readResolve,用于在反序列化过程中解析为DefaultListableBeanFactory实例。
- 首先从serializableFactories中根据id获取Reference实例。
- 如果Reference实例存在并且没有被垃圾回收,则获取实际的DefaultListableBeanFactory对象并返回。
- 否则,在原始工厂未找到的情况下,创建一个默认的DefaultListableBeanFactory实例作为回退值。 这个虚拟的DefaultListableBeanFactory实例将被设置serializationId为当前SerializedBeanFactoryReference的id。
java
private static class SerializedBeanFactoryReference implements Serializable {
private final String id;
public SerializedBeanFactoryReference(String id) {
this.id = id;
}
private Object readResolve() {
Reference<?> ref = serializableFactories.get(this.id);
if (ref != null) {
Object result = ref.get();
if (result != null) {
return result;
}
}
// Lenient fallback: dummy factory in case of original factory not found...
DefaultListableBeanFactory dummyFactory = new DefaultListableBeanFactory();
dummyFactory.serializationId = this.id;
return dummyFactory;
}
}
NestedDependencyDescriptor
NestedDependencyDescriptor类的主要目的是在原有的DependencyDescriptor基础上增加嵌套级别。它通过调用父类的构造方法和增加嵌套级别的方法,创建一个新的依赖描述符对象,用于表示嵌套元素的依赖关系。
具体实现步骤如下:
- NestedDependencyDescriptor类继承自DependencyDescriptor,表示嵌套元素的依赖描述符。
- NestedDependencyDescriptor类有一个构造方法,接受一个DependencyDescriptor类型的original参数。
- 在构造方法中,调用父类的构造方法,将original作为参数传递给父类构造方法。
- 调用increaseNestingLevel方法,增加嵌套级别。
java
/**
* A dependency descriptor marker for nested elements.
*/
private static class NestedDependencyDescriptor extends DependencyDescriptor {
public NestedDependencyDescriptor(DependencyDescriptor original) {
super(original);
increaseNestingLevel();
}
}
StreamDependencyDescriptor
StreamDependencyDescriptor类的主要目的是表示流型的依赖关系的描述符。它通过继承DependencyDescriptor类并添加一个额外的成员变量ordered来实现。构造方法用于初始化原始依赖描述符和有序标志。isOrdered方法用于获取是否为有序的标志。这个类可以用于标记流型依赖,并进行特殊处理。
具体实现步骤如下:
- StreamDependencyDescriptor类继承自DependencyDescriptor,表示流型依赖描述符。
- StreamDependencyDescriptor类有一个构造方法,接受一个DependencyDescriptor类型的original参数和一个boolean类型的ordered参数。
- 在构造方法中,调用父类的构造方法,将original作为参数传递给父类构造方法。
- 将ordered参数赋值给类的成员变量this.ordered。
- 类中还有一个isOrdered方法,用于获取是否为有序的标志。
java
/**
* A dependency descriptor marker for stream access to multiple elements.
*/
private static class StreamDependencyDescriptor extends DependencyDescriptor {
private final boolean ordered;
public StreamDependencyDescriptor(DependencyDescriptor original, boolean ordered) {
super(original);
this.ordered = ordered;
}
public boolean isOrdered() {
return this.ordered;
}
}
BeanObjectProvider<T>
该接口的主要目的是扩展ObjectProvider<T>
接口,并将其序列化。因为ObjectProvider<T>
接口可能在某些场景下需要被序列化(如在分布式系统中传递、在网络中传输),所以定义了BeanObjectProvider接口来表示在序列化过程中提供bean对象的能力。
java
private interface BeanObjectProvider<T> extends ObjectProvider<T>, Serializable {
}
DependencyObjectProvider
DependencyObjectProvider类的主要目的是根据依赖描述符和可选的bean名称来提供对应的bean对象。它实现了BeanObjectProvider接口,提供了获取bean对象的方法,并根据optional字段的值决定是否创建Optional类型的依赖对象。同时,还提供了获取、遍历和流化依赖对象的方法。
具体实现步骤如下:
- DependencyObjectProvider类实现了BeanObjectProvider
<Object>
接口。 - DependencyObjectProvider类拥有如下属性:
- descriptor:依赖描述符对象,用于解析依赖。
- optional:标识依赖是否为Optional类型。
- beanName:可选的bean名称。
- DependencyObjectProvider类有一个构造方法,接受DependencyDescriptor类型的descriptor和可选的String类型的beanName参数。
- 在构造方法中,根据传入的descriptor创建一个新的NestedDependencyDescriptor对象,并将其赋值给this.descriptor属性。
- 判断this.descriptor的依赖类型是否为Optional.class,如果是,则将this.optional字段设置为true,否则设置为false。
- 将传入的beanName赋值给this.beanName属性。
- 实现了BeanObjectProvider接口的getObject()方法、getObject(Object... args)方法、getIfAvailable()方法、ifAvailable(Consumer
<Object>
dependencyConsumer)方法、getIfUnique()方法、ifUnique(Consumer<Object>
dependencyConsumer)方法。 这些方法都是根据依赖描述符和bean名称解析依赖对象,并在必要时进行异常处理。 - 实现了BeanObjectProvider接口的stream()方法和orderedStream()方法,用于获取依赖对象的流。在orderedStream()方法中,在DependencyDescriptor的基础上创建StreamDependencyDescriptor对象,并调用doResolveDependency方法解析依赖对象,并返回结果流。
java
private class DependencyObjectProvider implements BeanObjectProvider<Object> {
private final DependencyDescriptor descriptor;
private final boolean optional;
@Nullable
private final String beanName;
public DependencyObjectProvider(DependencyDescriptor descriptor, @Nullable String beanName) {
this.descriptor = new NestedDependencyDescriptor(descriptor);
this.optional = (this.descriptor.getDependencyType() == Optional.class);
this.beanName = beanName;
}
@Override
public Object getObject() throws BeansException {
if (this.optional) {
return createOptionalDependency(this.descriptor, this.beanName);
}
else {
Object result = doResolveDependency(this.descriptor, this.beanName, null, null);
if (result == null) {
throw new NoSuchBeanDefinitionException(this.descriptor.getResolvableType());
}
return result;
}
}
@Override
public Object getObject(final Object... args) throws BeansException {
if (this.optional) {
return createOptionalDependency(this.descriptor, this.beanName, args);
}
else {
DependencyDescriptor descriptorToUse = new DependencyDescriptor(this.descriptor) {
@Override
public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory) {
return beanFactory.getBean(beanName, args);
}
};
Object result = doResolveDependency(descriptorToUse, this.beanName, null, null);
if (result == null) {
throw new NoSuchBeanDefinitionException(this.descriptor.getResolvableType());
}
return result;
}
}
@Override
@Nullable
public Object getIfAvailable() throws BeansException {
try {
if (this.optional) {
return createOptionalDependency(this.descriptor, this.beanName);
}
else {
DependencyDescriptor descriptorToUse = new DependencyDescriptor(this.descriptor) {
@Override
public boolean isRequired() {
return false;
}
};
return doResolveDependency(descriptorToUse, this.beanName, null, null);
}
}
catch (ScopeNotActiveException ex) {
// Ignore resolved bean in non-active scope
return null;
}
}
@Override
public void ifAvailable(Consumer<Object> dependencyConsumer) throws BeansException {
Object dependency = getIfAvailable();
if (dependency != null) {
try {
dependencyConsumer.accept(dependency);
}
catch (ScopeNotActiveException ex) {
// Ignore resolved bean in non-active scope, even on scoped proxy invocation
}
}
}
@Override
@Nullable
public Object getIfUnique() throws BeansException {
DependencyDescriptor descriptorToUse = new DependencyDescriptor(this.descriptor) {
@Override
public boolean isRequired() {
return false;
}
@Override
@Nullable
public Object resolveNotUnique(ResolvableType type, Map<String, Object> matchingBeans) {
return null;
}
};
try {
if (this.optional) {
return createOptionalDependency(descriptorToUse, this.beanName);
}
else {
return doResolveDependency(descriptorToUse, this.beanName, null, null);
}
}
catch (ScopeNotActiveException ex) {
// Ignore resolved bean in non-active scope
return null;
}
}
@Override
public void ifUnique(Consumer<Object> dependencyConsumer) throws BeansException {
Object dependency = getIfUnique();
if (dependency != null) {
try {
dependencyConsumer.accept(dependency);
}
catch (ScopeNotActiveException ex) {
// Ignore resolved bean in non-active scope, even on scoped proxy invocation
}
}
}
@Nullable
protected Object getValue() throws BeansException {
if (this.optional) {
return createOptionalDependency(this.descriptor, this.beanName);
}
else {
return doResolveDependency(this.descriptor, this.beanName, null, null);
}
}
@Override
public Stream<Object> stream() {
return resolveStream(false);
}
@Override
public Stream<Object> orderedStream() {
return resolveStream(true);
}
@SuppressWarnings("unchecked")
private Stream<Object> resolveStream(boolean ordered) {
DependencyDescriptor descriptorToUse = new StreamDependencyDescriptor(this.descriptor, ordered);
Object result = doResolveDependency(descriptorToUse, this.beanName, null, null);
return (result instanceof Stream ? (Stream<Object>) result : Stream.of(result));
}
}
Jsr330Factory
Jsr330Factory类的主要目的是用于创建依赖提供者对象。它拥有一个私有内部类Jsr330Provider,用于提供依赖对象。通过调用Jsr330Factory的createDependencyProvider方法,可以创建Jsr330Provider对象,并使用Provider<Object>
接口进行依赖获取。这样可以灵活地满足使用JSR-330标准的依赖注入需求。
具体实现步骤如下:
- Jsr330Factory类实现了Serializable接口,表示该类可以被序列化。
- Jsr330Factory类有一个createDependencyProvider方法,用于创建依赖提供者对象。
- 这个方法接受DependencyDescriptor类型的descriptor和可选的String类型的beanName参数。
- 在方法中,创建一个Jsr330Provider对象,将descriptor和beanName作为构造方法的参数传递进去,并返回该对象。
- Jsr330Factory类还有一个私有内部类Jsr330Provider的实现。
- Jsr330Provider类继承自DependencyObjectProvider,并实现了Provider
<Object>
接口。 - Jsr330Provider类有一个构造方法,接受DependencyDescriptor类型的descriptor和可选的String类型的beanName参数,并调用父类的构造方法进行初始化。
- 实现了Provider
<Object>
接口的get()方法,调用getValue()方法获取依赖对象并返回。
- Jsr330Provider类继承自DependencyObjectProvider,并实现了Provider
java
private class Jsr330Factory implements Serializable {
public Object createDependencyProvider(DependencyDescriptor descriptor, @Nullable String beanName) {
return new Jsr330Provider(descriptor, beanName);
}
private class Jsr330Provider extends DependencyObjectProvider implements Provider<Object> {
public Jsr330Provider(DependencyDescriptor descriptor, @Nullable String beanName) {
super(descriptor, beanName);
}
@Override
@Nullable
public Object get() throws BeansException {
return getValue();
}
}
}
FactoryAwareOrderSourceProvider
FactoryAwareOrderSourceProvider类的主要目的是通过查找实例与bean名称的映射关系,获取排序源(用于排序比较)。 在getOrderSource方法中,根据传入的实例obj,从映射instancesToBeanNames中查找对应的bean名称,并通过该bean名称获取相关的RootBeanDefinition。 然后,将工厂方法和目标类型作为排序源,添加到列表中,并返回列表。这样,OrderComparator可以使用这些排序源进行排序比较。
具体实现步骤如下:
- FactoryAwareOrderSourceProvider类实现了OrderComparator.OrderSourceProvider接口。
- FactoryAwareOrderSourceProvider类拥有一个成员变量instancesToBeanNames,是一个映射,用于将实例与对应的bean名称关联起来。
- FactoryAwareOrderSourceProvider类有一个构造方法,接受一个Map类型的instancesToBeanNames参数,并将其赋值给成员变量。
- 实现了OrderComparator.OrderSourceProvider接口的getOrderSource(Object obj)方法。
- 该方法根据传入的obj参数,在instancesToBeanNames映射中查找与之关联的bean名称。
- 如果找不到bean名称或者在容器中不存在该bean定义,则返回null。
- 如果找到bean名称,那么根据bean名称获取对应的RootBeanDefinition对象。
- 创建一个ArrayList对象sources用于存放排序源。
- 如果RootBeanDefinition中存在解析后的工厂方法(factoryMethod),则添加到sources列表中。
- 如果RootBeanDefinition中存在目标类型(targetType),并且不等于obj的实际类型,则添加到sources列表中。
- 将sources列表转换为数组并返回。
java
/**
* An {@link org.springframework.core.OrderComparator.OrderSourceProvider} implementation
* that is aware of the bean metadata of the instances to sort.
* <p>Lookup for the method factory of an instance to sort, if any, and let the
* comparator retrieve the {@link org.springframework.core.annotation.Order}
* value defined on it. This essentially allows for the following construct:
*/
private class FactoryAwareOrderSourceProvider implements OrderComparator.OrderSourceProvider {
private final Map<Object, String> instancesToBeanNames;
public FactoryAwareOrderSourceProvider(Map<Object, String> instancesToBeanNames) {
this.instancesToBeanNames = instancesToBeanNames;
}
@Override
@Nullable
public Object getOrderSource(Object obj) {
String beanName = this.instancesToBeanNames.get(obj);
if (beanName == null || !containsBeanDefinition(beanName)) {
return null;
}
RootBeanDefinition beanDefinition = getMergedLocalBeanDefinition(beanName);
List<Object> sources = new ArrayList<>(2);
Method factoryMethod = beanDefinition.getResolvedFactoryMethod();
if (factoryMethod != null) {
sources.add(factoryMethod);
}
Class<?> targetType = beanDefinition.getTargetType();
if (targetType != null && targetType != obj.getClass()) {
sources.add(targetType);
}
return sources.toArray();
}
}