当前位置:首页 > 科技  > 软件

详解Spring支持的各种数据类型的注入,你都用过哪些?

来源: 责编: 时间:2023-09-18 21:42:16 246观看
导读1 判断类型注入的属性判断其类型:OptionalObjectFactoryObjectProviderjavax.inject.Providerpublic class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListable

1 判断类型

注入的属性判断其类型:3T328资讯网——每日最新资讯28at.com

  1. Optional
  2. ObjectFactory
  3. ObjectProvider
  4. javax.inject.Provider
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {    private static Class<?> javaxInjectProviderClass;    static {        try {            javaxInjectProviderClass =                    ClassUtils.forName("javax.inject.Provider", DefaultListableBeanFactory.class.getClassLoader());        } catch (ClassNotFoundException ex) {            javaxInjectProviderClass = null;        }    }    public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,            @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {        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 {            // 判断是否有@Lazy注解,如果有该注解那么会创建代理对象,否则返回null            // 总结:如果注入的属性有@Lazy注解,那么会返回由ProxyFactory对象创建的代理对象            Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(descriptor, requestingBeanName);            if (result == null) {                // 解析查找依赖注入的对象                result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);            }            return result;        }    }}

2 查找依赖对象

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {  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();      // 判断需要注入的类型是否是一个集合(如何:List<Users> beans)      // 2.1       Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);      if (multipleBeans != null) {          return multipleBeans;      }      // 查找与所需类型匹配的bean实例      // 2.2      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) {          // 在这里会判断多个Bean中是否有一个@Primary注解的Bean          // 如果没有@Primary,继续获取是否有@Priority(优先级)注解          // 如果没有则返回null,如果有则返回值越小的优先级越高(如果有多个优先级一样,则系统报错)          // 如果上面都返回的null,那么最后会通过beanName进行匹配          autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);          if (autowiredBeanName == null) {              if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {                  // 如果是必须的 或者 不是集合类型的Bean注入;那么这里抛出异常                  return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);              } else {                  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);    }  }}

2.1 判断集合类型

判断需要注入的属性的数据类型是否是如下几种。3T328资讯网——每日最新资讯28at.com

  1. StreamDependencyDescriptor
  2. Array
  3. Collection
  4. Map
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {  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;    }  }}

2.2 查找Bean

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {  protected Map<String, Object> findAutowireCandidates(          @Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {    // 通过类型获取指定类型的Bean    String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(            this, requiredType, true, descriptor.isEager());    Map<String, Object> result = CollectionUtils.newLinkedHashMap(candidateNames.length);    // resolvableDependencies 集合中保存了,容器内置的和自定义注册的依赖注入对象    //(如:HttpServletRequest对象的注入为该集合内部指定的对象)    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;  }}

以上就是Spring在注入属性的时候会判断是什么数据类型进行相应的操作3T328资讯网——每日最新资讯28at.com

完毕!!!3T328资讯网——每日最新资讯28at.com

本文链接://www.dmpip.com//www.dmpip.com/showinfo-26-10486-0.html详解Spring支持的各种数据类型的注入,你都用过哪些?

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: Springboot — 用更优雅的方式发HTTP请求(RestTemplate详解)

下一篇: 为什么我更喜欢基于主干的开发

标签:
  • 热门焦点
  • 一加首款折叠屏!一加Open渲染图出炉:罕见单手可握小尺寸

    一加首款折叠屏!一加Open渲染图出炉:罕见单手可握小尺寸

    8月5日消息,此前就有爆料称,一加首款折叠屏手机将会在第三季度上市,如今随着时间临近,新机的各种消息也开始浮出水面。据悉,这款新机将会被命名为&ldquo;On
  • 线程通讯的三种方法!通俗易懂

    线程通讯的三种方法!通俗易懂

    线程通信是指多个线程之间通过某种机制进行协调和交互,例如,线程等待和通知机制就是线程通讯的主要手段之一。 在 Java 中,线程等待和通知的实现手段有以下几种方式:Object 类下
  • Rust中的高吞吐量流处理

    Rust中的高吞吐量流处理

    作者 | Noz编译 | 王瑞平本篇文章主要介绍了Rust中流处理的概念、方法和优化。作者不仅介绍了流处理的基本概念以及Rust中常用的流处理库,还使用这些库实现了一个流处理程序
  • .NET 程序的 GDI 句柄泄露的再反思

    .NET 程序的 GDI 句柄泄露的再反思

    一、背景1. 讲故事上个月我写过一篇 如何洞察 C# 程序的 GDI 句柄泄露 文章,当时用的是 GDIView + WinDbg 把问题搞定,前者用来定位泄露资源,后者用来定位泄露代码,后面有朋友反
  • 虚拟键盘 API 的妙用

    虚拟键盘 API 的妙用

    你是否在遇到过这样的问题:移动设备上有一个固定元素,当激活虚拟键盘时,该元素被隐藏在了键盘下方?多年来,这一直是 Web 上的默认行为,在本文中,我们将探讨这个问题、为什么会发生
  • 2023年,我眼中的字节跳动

    2023年,我眼中的字节跳动

    此时此刻(2023年7月),字节跳动从未上市,也从未公布过任何官方的上市计划;但是这并不妨碍它成为中国最受关注的互联网公司之一。从2016-17年的抖音强势崛起,到2018年的&ldquo;头腾
  • 大厂卷向扁平化

    大厂卷向扁平化

    来源:新熵作者丨南枝 编辑丨月见大厂职级不香了。俗话说,兵无常势,水无常形,互联网企业调整职级体系并不稀奇。7月13日,淘宝天猫集团启动了近年来最大的人力制度改革,目前已形成一
  • iQOO Neo8 Pro真机谍照曝光:天玑9200+和V1+旗舰双芯加持

    iQOO Neo8 Pro真机谍照曝光:天玑9200+和V1+旗舰双芯加持

    去年10月,iQOO推出了iQOO Neo7系列机型,不仅搭载了天玑9000+,而且是同价位唯一一款天玑9000+直屏旗舰,一经上市便受到了用户的广泛关注。在时隔半年后,
  • OPPO K11样张首曝:千元机影像“卷”得真不错!

    OPPO K11样张首曝:千元机影像“卷”得真不错!

    一直以来,OPPO K系列机型都保持着较为均衡的产品体验,历来都是2K价位的明星机型,去年推出的OPPO K10和OPPO K10 Pro两款机型凭借各自的出色配置,堪称有
Top
Baidu
map