IT评测·应用市场-qidao123.com技术社区

标题: DefaultListableBeanFactory [打印本页]

作者: 曹旭辉    时间: 2025-4-7 05:39
标题: DefaultListableBeanFactory
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的表。
  1. /** Map of bean definition objects, keyed by bean name. */
  2. private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
复制代码
getbean方法

DefaultListableBeanFactory是Bean工厂的一个默认实现,DefaultListableBeanFactory是Bean工厂的一个默认实现。截取DefaultListableBeanFactory中与getBean方法。
可以发现getBean有两种方式获取bean:

  1.    //---------------------------------------------------------------------
  2. // Implementation of remaining BeanFactory methods
  3. //---------------------------------------------------------------------
  4. //这个方式属于是扩展了getBean的方式,通过类型获取Bean
  5. @Override
  6. public <T> T getBean(Class<T> requiredType) throws BeansException {
  7.         return getBean(requiredType, (Object[]) null);
  8. }
  9. @SuppressWarnings("unchecked")
  10. @Override
  11. public <T> T getBean(Class<T> requiredType, @Nullable Object... args) throws BeansException {
  12.         Assert.notNull(requiredType, "Required type must not be null");
  13.        //根据类型解析bean
  14.         Object resolved = resolveBean(ResolvableType.forRawClass(requiredType), args, false);
  15.         if (resolved == null) {
  16.                 throw new NoSuchBeanDefinitionException(requiredType);
  17.         }
  18.         return (T) resolved;
  19. }
复制代码
setAutowireCandidateResolver方法

这是一个普通的set方法,为什么我还要介绍它呢,由于这个set方法能启动扩展DefaultListableBeanFactory的功能。通过该方法给DefaultListableBeanFactory扩展主动装配的解析器。
可以通过该方法添加格外的主动装配解析器,如:QualifierAnnotationAutowireCandidateResolver提供@Qualifier注解解析的功能和@Autowire
  1. /**
  2. * Set a custom autowire candidate resolver for this BeanFactory to use
  3. * when deciding whether a bean definition should be considered as a
  4. * candidate for autowiring.
  5. */
  6. public void setAutowireCandidateResolver(AutowireCandidateResolver autowireCandidateResolver) {
  7.         Assert.notNull(autowireCandidateResolver, "AutowireCandidateResolver must not be null");
  8.         if (autowireCandidateResolver instanceof BeanFactoryAware) {
  9.                 if (System.getSecurityManager() != null) {
  10.                         AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
  11.                                 ((BeanFactoryAware) autowireCandidateResolver).setBeanFactory(this);
  12.                                 return null;
  13.                         }, getAccessControlContext());
  14.                 }
  15.                 else {
  16.                         ((BeanFactoryAware) autowireCandidateResolver).setBeanFactory(this);
  17.                 }
  18.         }
  19.         this.autowireCandidateResolver = autowireCandidateResolver;
  20. }
复制代码
resolveDependency方法

resolveDependency(DependencyDescriptor descriptor, String requestingBeanName, Set<String> autowiredBeanNames, TypeConverter typeConverter)方法,找到对应的依赖 Bean,获取 Bean 的实例对象时,构造器注入的参数也是通过该方法获取的,依赖注入底层也是通过该方法实现的,这里我们对该方法一探究竟
  1. // DefaultListableBeanFactory.java
  2. @Override
  3. @Nullable
  4. public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
  5.         @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
  6.     // <1> 设置参数名称探测器,例如通过它获取方法参数的名称
  7.     descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
  8.     // <2> 如果依赖类型为 Optional 类型
  9.     if (Optional.class == descriptor.getDependencyType()) {
  10.         // 调用 `createOptionalDependency(...)` 方法,先将 `descriptor` 注入表述器封装成 NestedDependencyDescriptor 对象
  11.         // 底层处理和下面的 `5.2` 相同
  12.         return createOptionalDependency(descriptor, requestingBeanName);
  13.     }
  14.     // <3> 否则,如果依赖类型为 ObjectFactory 或 ObjectProvider 类型
  15.     else if (ObjectFactory.class == descriptor.getDependencyType() || ObjectProvider.class == descriptor.getDependencyType()) {
  16.         // 返回一个 DependencyObjectProvider 私有内部类对象,并没有获取到实例的 Bean,需要调用其 getObject() 方法获取目标对象
  17.         return new DependencyObjectProvider(descriptor, requestingBeanName);
  18.     }
  19.     // <4> 否则,如果依赖类型为 javax.inject.Provider 类型
  20.     else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
  21.         // 返回一个 Jsr330Provider 私有内部类对象,该对象也继承 DependencyObjectProvider
  22.         return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
  23.     }
  24.     // <5> 否则,通用的处理逻辑
  25.     else {
  26.         // <5.1> 先通过 AutowireCandidateResolver 尝试获取一个代理对象,延迟依赖注入则会返回一个代理对象
  27.         Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(descriptor, requestingBeanName);
  28.         // <5.2> 如果上面没有返回代理对象,则进行处理,调用 `doResolveDependency(...)` 方法
  29.         if (result == null) {
  30.             result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
  31.         }
  32.         return result;
  33.     }
  34. }
复制代码
doResolveDependency方法

  1. // DefaultListableBeanFactory.java
  2. @Nullable
  3. public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
  4.         @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
  5.     // 设置当前线程的注入点,并返回上次的注入点,属于嵌套注入的一个保护点
  6.     InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
  7.     try {
  8.         // <1> 针对给定的工厂给定一个快捷实现的方式,暂时忽略
  9.         // 例如考虑一些预先解析的信息,在进入所有 Bean 的常规类型匹配算法之前,解析算法将首先尝试通过此方法解析快捷方式
  10.         Object shortcut = descriptor.resolveShortcut(this);
  11.         if (shortcut != null) {
  12.             // 返回快捷的解析信息
  13.             return shortcut;
  14.         }
  15.         // 依赖的类型
  16.         Class<?> type = descriptor.getDependencyType();
  17.         // <2> 获取注解中的 value 对应的值,例如 @Value、@Qualifier 注解配置的 value 属性值,注意 @Autowired 没有 value 属性配置
  18.         Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
  19.         if (value != null) {
  20.             if (value instanceof String) {
  21.                 // <2.1> 解析注解中的 value,因为可能是占位符,需要获取到相应的数据
  22.                 String strVal = resolveEmbeddedValue((String) value);
  23.                 BeanDefinition bd = (beanName != null && containsBean(beanName) ?
  24.                         getMergedBeanDefinition(beanName) : null);
  25.                 value = evaluateBeanDefinitionString(strVal, bd);
  26.             }
  27.             TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
  28.             try {
  29.                 // <2.2> 进行类型转换,并返回
  30.                 return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
  31.             }
  32.             catch (UnsupportedOperationException ex) {
  33.                 // A custom TypeConverter which does not support TypeDescriptor resolution...
  34.                 return (descriptor.getField() != null ?
  35.                         converter.convertIfNecessary(value, type, descriptor.getField()) :
  36.                         converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
  37.             }
  38.         }
  39.         // <3> 解析复合的依赖对象(Array、Collection、Map 类型),获取该属性元素类型的 Bean 们
  40.         // 底层和第 `4` 原理一样,这里会将 `descriptor` 封装成 MultiElementDescriptor 类型
  41.         Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
  42.         if (multipleBeans != null) {
  43.             return multipleBeans;
  44.         }
  45.         // <4> 查找与类型相匹配的 Bean 们
  46.         // 返回结果:key -> beanName;value -> 对应的 Bean
  47.         Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
  48.         // <5> 如果一个都没找到
  49.         if (matchingBeans.isEmpty()) {
  50.             // <5.1> 如果 @Autowired 配置的 required 为 true,表示必须,则抛出异常
  51.             if (isRequired(descriptor)) {
  52.                 raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
  53.             }
  54.             // <5.2> 否则,返回一个空对象
  55.             return null;
  56.         }
  57.         String autowiredBeanName;
  58.         Object instanceCandidate;
  59.         // <6> 如果匹配的 Bean 有多个,则需要找出最优先的那个
  60.         if (matchingBeans.size() > 1) {
  61.             // <6.1> 找到最匹配的那个 Bean,通过 @Primary 或者 @Priority 来决定,或者通过名称决定
  62.             autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
  63.             if (autowiredBeanName == null) {
  64.                 if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
  65.                     // <6.2> 如果没有找到最匹配的 Bean,则抛出 NoUniqueBeanDefinitionException 异常
  66.                     return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
  67.                 }
  68.                 else {
  69.                     // In case of an optional Collection/Map, silently ignore a non-unique case:
  70.                     // possibly it was meant to be an empty collection of multiple regular beans
  71.                     // (before 4.3 in particular when we didn't even look for collection beans).
  72.                     return null;
  73.                 }
  74.             }
  75.             // <6.3> 获取到最匹配的 Bean,传值引用给 `instanceCandidate`
  76.             instanceCandidate = matchingBeans.get(autowiredBeanName);
  77.         }
  78.         // <7> 否则,只有一个 Bean,则直接使用其作为最匹配的 Bean
  79.         else {
  80.             // We have exactly one match.
  81.             Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
  82.             autowiredBeanName = entry.getKey();
  83.             instanceCandidate = entry.getValue();
  84.         }
  85.         // <8> 将依赖注入的 Bean 的名称添加至方法入参 `autowiredBeanNames` 集合,里面保存依赖注入的 beanName
  86.         if (autowiredBeanNames != null) {
  87.             autowiredBeanNames.add(autowiredBeanName);
  88.         }
  89.         // <9> 如果匹配的 Bean 是 Class 对象,则根据其 beanName 依赖查找到对应的 Bean
  90.         if (instanceCandidate instanceof Class) {
  91.             instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
  92.         }
  93.         Object result = instanceCandidate;
  94.         if (result instanceof NullBean) {
  95.             if (isRequired(descriptor)) {
  96.                 raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
  97.             }
  98.             result = null;
  99.         }
  100.         if (!ClassUtils.isAssignableValue(type, result)) {
  101.             throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
  102.         }
  103.         // <10> 返回依赖注入的 Bean
  104.         return result;
  105.     }
  106.     finally {
  107.         // 设置当前线程的注入点为上一次的注入点,因为本次注入结束了
  108.         ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
  109.     }
  110. }
复制代码
findAutowireCandidates 方法

  1. // DefaultListableBeanFactory.java
  2. protected Map<String, Object> findAutowireCandidates(
  3.         @Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
  4.     // <1> 从当前上下文找到该类型的 Bean 们(根据类型)
  5.     String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
  6.             this, requiredType, true, descriptor.isEager());
  7.     // <2> 定义一个 Map 对象 `result`,用于保存符合条件的 Bean
  8.     Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);
  9.     /**
  10.      * <3> 遍历 Spring 内部已处理的依赖对象集合,可以跳到 AbstractApplicationContext#prepareBeanFactory 方法中看看
  11.      * 会有一下几个内置处理对象:
  12.      * BeanFactory 类型 -> 返回 DefaultListableBeanFactory
  13.      * ResourceLoader、ApplicationEventPublisher、ApplicationContext 类型 ->  返回 ApplicationContext 对象
  14.      */
  15.     for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
  16.         Class<?> autowiringType = classObjectEntry.getKey();
  17.         if (autowiringType.isAssignableFrom(requiredType)) {
  18.             Object autowiringValue = classObjectEntry.getValue();
  19.             autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
  20.             if (requiredType.isInstance(autowiringValue)) {
  21.                 result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
  22.                 break;
  23.             }
  24.         }
  25.     }
  26.     // <4> 遍历第 `1` 步找到的 Bean 的名称们
  27.     for (String candidate : candidateNames) {
  28.         // <4.1> 如果满足下面两个条件,则添加至 `result` 集合中
  29.         if (!isSelfReference(beanName, candidate) // 如果不是自引用(这个 Bean 不是在需要依赖它的 Bean 的内部定义的)
  30.                 && isAutowireCandidate(candidate, descriptor)) { // 符合注入的条件
  31.             addCandidateEntry(result, candidate, descriptor, requiredType);
  32.         }
  33.     }
  34.     // <5> 如果没有找到符合条件的 Bean,则再尝试获取
  35.     if (result.isEmpty()) {
  36.         boolean multiple = indicatesMultipleBeans(requiredType);
  37.         // Consider fallback matches if the first pass failed to find anything...
  38.         DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
  39.         // <5.1> 再次遍历第 `1` 步找到的 Bean 的名称们
  40.         for (String candidate : candidateNames) {
  41.             // <5.2> 如果满足下面三个条件,则添加至 `result` 集合中
  42.             if (!isSelfReference(beanName, candidate) // 如果不是自引用(这个 Bean 不是在需要依赖它的 Bean 的内部定义的)
  43.                     && isAutowireCandidate(candidate, fallbackDescriptor) // 符合注入的条件
  44.                     && (!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) { // 不是复合类型,或者有 @Qualifier 注解
  45.                 addCandidateEntry(result, candidate, descriptor, requiredType);
  46.             }
  47.         }
  48.         // <6> 如果还没有找到符合条件的 Bean,则再尝试获取
  49.         // 和上面第 `5` 步的区别在于必须是自引用(这个 Bean 不是在需要依赖它的 Bean 的内部定义的)
  50.         if (result.isEmpty() && !multiple) {
  51.             // Consider self references as a final pass...
  52.             // but in the case of a dependency collection, not the very same bean itself.
  53.             for (String candidate : candidateNames) {
  54.                 if (isSelfReference(beanName, candidate)
  55.                         && (!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate))
  56.                         && isAutowireCandidate(candidate, fallbackDescriptor)) {
  57.                     addCandidateEntry(result, candidate, descriptor, requiredType);
  58.                 }
  59.             }
  60.         }
  61.     }
  62.     // <7> 返回 `result`,符合条件的 Bean
  63.     return result;
  64. }
复制代码
determineAutowireCandidate 方法

determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor)方法,找到最匹配的那个依赖注入对象,如下:
  1. @Nullable
  2. protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
  3.     Class<?> requiredType = descriptor.getDependencyType();
  4.     // <1> 尝试获取一个 @Primary 注解标注的 Bean,如果有找到多个则会抛出异常
  5.     String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
  6.     // <2> 如果第 `1` 步找到了则直接返回
  7.     if (primaryCandidate != null) {
  8.         return primaryCandidate;
  9.     }
  10.     // <3> 尝试找到 @Priority 注解优先级最高的那个 Bean,如果存在相同的优先级则会抛出异常
  11.     String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
  12.     // <4> 如果第 `3` 步找到了则直接返回
  13.     if (priorityCandidate != null) {
  14.         return priorityCandidate;
  15.     }
  16.     // Fallback
  17.     // <5> 兜底方法,遍历所有的 Bean
  18.     for (Map.Entry<String, Object> entry : candidates.entrySet()) {
  19.         String candidateName = entry.getKey();
  20.         Object beanInstance = entry.getValue();
  21.         // <5.1> 如果满足下面其中一个条件则直接返回
  22.         if ((beanInstance != null
  23.             && this.resolvableDependencies.containsValue(beanInstance)) // 该 Bean 为 Spring 内部可处理的 Bean,例如 ApplicationContext
  24.             || matchesBeanName(candidateName, descriptor.getDependencyName())) { // 名称相匹配
  25.             return candidateName;
  26.         }
  27.     }
  28.     // <6> 上面都没选出来则返回一个空对象
  29.     return null;
  30. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 IT评测·应用市场-qidao123.com技术社区 (https://dis.qidao123.com/) Powered by Discuz! X3.4