DefaultListableBeanFactory

文章目录

DefaultListableBeanFactory介绍

BeanFactory是个Factory,也就是IOC容器或对象工厂,而DefaultListableBeanFactory是Bean工厂的一个默认实现,DefaultListableBeanFactory提供了原始的BeanFactory的功能,如:对外提供getBean()方法,维护一张beanDefinitionMap

继承关系

DefaultListableBeanFactory继承关系如下,可以看出DefaultListableBeanFactory还有子类XmlBeanFactory

接口实现

下图列出了DefaultListableBeanFactory的接口实现和继承图,DefaultListableBeanFactory实现了BeanDefinitionRegistry接口,并且实现BeanFactory接口,提供了基本的BeanFactory功能。

BeanDefinitionRegistry是一个接口,它定义了关于BeanDefinition的注册、移除、查询等一系列的操作。

BeanFactory是IOC容器的核心接口,它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。

源码码解析

属性成员

beanDefinitionMapDefaultListableBeanFactory作为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;
}
相关推荐
优雅的38度16 分钟前
SpringBoot 3.0+ 整合 Swagger 3.0
java·后端
Pitayafruit19 分钟前
🔥 Spring Boot 3 整合 zxing:轻松生成二维码的指南
java·spring boot·后端
雷渊21 分钟前
redis如何实现发布/订阅功能?
java·后端·面试
雷渊21 分钟前
redis中的zset怎么实现的?
java·后端·面试
Anarkh_Lee23 分钟前
图解JVM - 21.JVM运行时参数
java·jvm·后端
Anarkh_Lee26 分钟前
图解JVM - 22.分析GC日志
java·jvm·后端
kong790692832 分钟前
SpringBoot整合SSM
java·spring boot·ssm
骑牛小道士33 分钟前
java基础使用- 泛型
java·开发语言
LeonNo1135 分钟前
Spring常见问题复习
java·spring·rpc
KNeeg_1 小时前
SpringSecurity框架入门
java·spring·spring cloud·springsecurity