文章目录
-
- DefaultListableBeanFactory介绍
- 继承关系
- 源码码解析
-
- 属性成员
- getbean方法
- setAutowireCandidateResolver方法
- resolveDependency方法
-
- doResolveDependency方法
- [findAutowireCandidates 方法](#findAutowireCandidates 方法)
- [determineAutowireCandidate 方法](#determineAutowireCandidate 方法)
DefaultListableBeanFactory介绍
BeanFactory
是个Factory,也就是IOC容器或对象工厂,而DefaultListableBeanFactory
是Bean工厂的一个默认实现,DefaultListableBeanFactory
提供了原始的BeanFactory
的功能,如:对外提供getBean()
方法,维护一张beanDefinitionMap
表
继承关系
DefaultListableBeanFactory
继承关系如下,可以看出DefaultListableBeanFactory
还有子类XmlBeanFactory
接口实现
下图列出了DefaultListableBeanFactory
的接口实现和继承图,DefaultListableBeanFactory
实现了BeanDefinitionRegistry
接口,并且实现BeanFactory
接口,提供了基本的BeanFactory
功能。
BeanDefinitionRegistry
是一个接口,它定义了关于BeanDefinition
的注册、移除、查询等一系列的操作。
BeanFactory
是IOC容器的核心接口,它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。
源码码解析
属性成员
beanDefinitionMap
:DefaultListableBeanFactory
作为BeanFactory
默认是维护这一张beanDefinition
的表。
java
/** Map of bean definition objects, keyed by bean name. */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
getbean方法
DefaultListableBeanFactory
是Bean工厂的一个默认实现,DefaultListableBeanFactory
是Bean工厂的一个默认实现。截取DefaultListableBeanFactory
中与getBean方法。
可以发现getBean有两种方式获取bean:
- 根据名称获取Bean,这个方法继承于
AbstractBeanFactory
- 根据类型获取Bean,这个方法实现于
DefaultListableBeanFactory
,属于扩展了getBean
方式
java
//---------------------------------------------------------------------
// Implementation of remaining BeanFactory methods
//---------------------------------------------------------------------
//这个方式属于是扩展了getBean的方式,通过类型获取Bean
@Override
public <T> T getBean(Class<T> requiredType) throws BeansException {
return getBean(requiredType, (Object[]) null);
}
@SuppressWarnings("unchecked")
@Override
public <T> T getBean(Class<T> requiredType, @Nullable Object... args) throws BeansException {
Assert.notNull(requiredType, "Required type must not be null");
//根据类型解析bean
Object resolved = resolveBean(ResolvableType.forRawClass(requiredType), args, false);
if (resolved == null) {
throw new NoSuchBeanDefinitionException(requiredType);
}
return (T) resolved;
}
setAutowireCandidateResolver方法
这是一个普通的set方法,为什么我还要介绍它呢,因为这个set方法能启动扩展DefaultListableBeanFactory
的功能。通过该方法给DefaultListableBeanFactory
扩展自动装配的解析器。
可以通过该方法添加格外的自动装配解析器,如:QualifierAnnotationAutowireCandidateResolver
提供@Qualifier
注解解析的功能和@Autowire
java
/**
* Set a custom autowire candidate resolver for this BeanFactory to use
* when deciding whether a bean definition should be considered as a
* candidate for autowiring.
*/
public void setAutowireCandidateResolver(AutowireCandidateResolver autowireCandidateResolver) {
Assert.notNull(autowireCandidateResolver, "AutowireCandidateResolver must not be null");
if (autowireCandidateResolver instanceof BeanFactoryAware) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
((BeanFactoryAware) autowireCandidateResolver).setBeanFactory(this);
return null;
}, getAccessControlContext());
}
else {
((BeanFactoryAware) autowireCandidateResolver).setBeanFactory(this);
}
}
this.autowireCandidateResolver = autowireCandidateResolver;
}
resolveDependency方法
resolveDependency(DependencyDescriptor descriptor, String requestingBeanName, Set<String> autowiredBeanNames, TypeConverter typeConverter)
方法,找到对应的依赖 Bean,获取 Bean 的实例对象时,构造器注入的参数也是通过该方法获取的,依赖注入底层也是通过该方法实现的,这里我们对该方法一探究竟
java
// DefaultListableBeanFactory.java
@Override
@Nullable
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
// <1> 设置参数名称探测器,例如通过它获取方法参数的名称
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
// <2> 如果依赖类型为 Optional 类型
if (Optional.class == descriptor.getDependencyType()) {
// 调用 `createOptionalDependency(...)` 方法,先将 `descriptor` 注入表述器封装成 NestedDependencyDescriptor 对象
// 底层处理和下面的 `5.2` 相同
return createOptionalDependency(descriptor, requestingBeanName);
}
// <3> 否则,如果依赖类型为 ObjectFactory 或 ObjectProvider 类型
else if (ObjectFactory.class == descriptor.getDependencyType() || ObjectProvider.class == descriptor.getDependencyType()) {
// 返回一个 DependencyObjectProvider 私有内部类对象,并没有获取到实例的 Bean,需要调用其 getObject() 方法获取目标对象
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
// <4> 否则,如果依赖类型为 javax.inject.Provider 类型
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
// 返回一个 Jsr330Provider 私有内部类对象,该对象也继承 DependencyObjectProvider
return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
}
// <5> 否则,通用的处理逻辑
else {
// <5.1> 先通过 AutowireCandidateResolver 尝试获取一个代理对象,延迟依赖注入则会返回一个代理对象
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(descriptor, requestingBeanName);
// <5.2> 如果上面没有返回代理对象,则进行处理,调用 `doResolveDependency(...)` 方法
if (result == null) {
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
doResolveDependency方法
java
// DefaultListableBeanFactory.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 {
// <1> 针对给定的工厂给定一个快捷实现的方式,暂时忽略
// 例如考虑一些预先解析的信息,在进入所有 Bean 的常规类型匹配算法之前,解析算法将首先尝试通过此方法解析快捷方式
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
// 返回快捷的解析信息
return shortcut;
}
// 依赖的类型
Class<?> type = descriptor.getDependencyType();
// <2> 获取注解中的 value 对应的值,例如 @Value、@Qualifier 注解配置的 value 属性值,注意 @Autowired 没有 value 属性配置
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
if (value instanceof String) {
// <2.1> 解析注解中的 value,因为可能是占位符,需要获取到相应的数据
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 {
// <2.2> 进行类型转换,并返回
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()));
}
}
// <3> 解析复合的依赖对象(Array、Collection、Map 类型),获取该属性元素类型的 Bean 们
// 底层和第 `4` 原理一样,这里会将 `descriptor` 封装成 MultiElementDescriptor 类型
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
// <4> 查找与类型相匹配的 Bean 们
// 返回结果:key -> beanName;value -> 对应的 Bean
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
// <5> 如果一个都没找到
if (matchingBeans.isEmpty()) {
// <5.1> 如果 @Autowired 配置的 required 为 true,表示必须,则抛出异常
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
// <5.2> 否则,返回一个空对象
return null;
}
String autowiredBeanName;
Object instanceCandidate;
// <6> 如果匹配的 Bean 有多个,则需要找出最优先的那个
if (matchingBeans.size() > 1) {
// <6.1> 找到最匹配的那个 Bean,通过 @Primary 或者 @Priority 来决定,或者通过名称决定
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
// <6.2> 如果没有找到最匹配的 Bean,则抛出 NoUniqueBeanDefinitionException 异常
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;
}
}
// <6.3> 获取到最匹配的 Bean,传值引用给 `instanceCandidate`
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
// <7> 否则,只有一个 Bean,则直接使用其作为最匹配的 Bean
else {
// We have exactly one match.
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
// <8> 将依赖注入的 Bean 的名称添加至方法入参 `autowiredBeanNames` 集合,里面保存依赖注入的 beanName
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
// <9> 如果匹配的 Bean 是 Class 对象,则根据其 beanName 依赖查找到对应的 Bean
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());
}
// <10> 返回依赖注入的 Bean
return result;
}
finally {
// 设置当前线程的注入点为上一次的注入点,因为本次注入结束了
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}
findAutowireCandidates 方法
java
// DefaultListableBeanFactory.java
protected Map<String, Object> findAutowireCandidates(
@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
// <1> 从当前上下文找到该类型的 Bean 们(根据类型)
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
// <2> 定义一个 Map 对象 `result`,用于保存符合条件的 Bean
Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);
/**
* <3> 遍历 Spring 内部已处理的依赖对象集合,可以跳到 AbstractApplicationContext#prepareBeanFactory 方法中看看
* 会有一下几个内置处理对象:
* BeanFactory 类型 -> 返回 DefaultListableBeanFactory
* ResourceLoader、ApplicationEventPublisher、ApplicationContext 类型 -> 返回 ApplicationContext 对象
*/
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;
}
}
}
// <4> 遍历第 `1` 步找到的 Bean 的名称们
for (String candidate : candidateNames) {
// <4.1> 如果满足下面两个条件,则添加至 `result` 集合中
if (!isSelfReference(beanName, candidate) // 如果不是自引用(这个 Bean 不是在需要依赖它的 Bean 的内部定义的)
&& isAutowireCandidate(candidate, descriptor)) { // 符合注入的条件
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
// <5> 如果没有找到符合条件的 Bean,则再尝试获取
if (result.isEmpty()) {
boolean multiple = indicatesMultipleBeans(requiredType);
// Consider fallback matches if the first pass failed to find anything...
DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
// <5.1> 再次遍历第 `1` 步找到的 Bean 的名称们
for (String candidate : candidateNames) {
// <5.2> 如果满足下面三个条件,则添加至 `result` 集合中
if (!isSelfReference(beanName, candidate) // 如果不是自引用(这个 Bean 不是在需要依赖它的 Bean 的内部定义的)
&& isAutowireCandidate(candidate, fallbackDescriptor) // 符合注入的条件
&& (!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) { // 不是复合类型,或者有 @Qualifier 注解
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
// <6> 如果还没有找到符合条件的 Bean,则再尝试获取
// 和上面第 `5` 步的区别在于必须是自引用(这个 Bean 不是在需要依赖它的 Bean 的内部定义的)
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);
}
}
}
}
// <7> 返回 `result`,符合条件的 Bean
return result;
}
determineAutowireCandidate 方法
determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor)
方法,找到最匹配的那个依赖注入对象,如下:
java
@Nullable
protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
Class<?> requiredType = descriptor.getDependencyType();
// <1> 尝试获取一个 @Primary 注解标注的 Bean,如果有找到多个则会抛出异常
String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
// <2> 如果第 `1` 步找到了则直接返回
if (primaryCandidate != null) {
return primaryCandidate;
}
// <3> 尝试找到 @Priority 注解优先级最高的那个 Bean,如果存在相同的优先级则会抛出异常
String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
// <4> 如果第 `3` 步找到了则直接返回
if (priorityCandidate != null) {
return priorityCandidate;
}
// Fallback
// <5> 兜底方法,遍历所有的 Bean
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
String candidateName = entry.getKey();
Object beanInstance = entry.getValue();
// <5.1> 如果满足下面其中一个条件则直接返回
if ((beanInstance != null
&& this.resolvableDependencies.containsValue(beanInstance)) // 该 Bean 为 Spring 内部可处理的 Bean,例如 ApplicationContext
|| matchesBeanName(candidateName, descriptor.getDependencyName())) { // 名称相匹配
return candidateName;
}
}
// <6> 上面都没选出来则返回一个空对象
return null;
}