【小家Spring】Spring标准处理组件大合集(ParameterNameDiscoverer、AutowireCandidateResolver、ResolvableType。。。)(中)

简介: 【小家Spring】Spring标准处理组件大合集(ParameterNameDiscoverer、AutowireCandidateResolver、ResolvableType。。。)(中)

AutowireCandidateResolver:


Strategy interface for determining whether a specific bean definition qualifies as an autowire candidate for a specific dependency.


策略接口,对特定的依赖,这个接口决定一个特定的bean definition是否满足作为自动绑定的备选项


// 本接口Spring2.5就提供了
public interface AutowireCandidateResolver {
  default boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
    return bdHolder.getBeanDefinition().isAutowireCandidate();
  }
  // Spring5.0后提供
  default boolean isRequired(DependencyDescriptor descriptor) {
    return descriptor.isRequired();
  }
  // 3.0后提供
  @Nullable
  default Object getSuggestedValue(DependencyDescriptor descriptor) {
    return null;
  }
  // 4.0后提供
  @Nullable
  default Object getLazyResolutionProxyIfNecessary(DependencyDescriptor descriptor, @Nullable String beanName) {
    return null;
  }
}


继承关系如下:


image.png


SimpleAutowireCandidateResolver没有任何实现,就是一个Adapter

GenericTypeAwareAutowireCandidateResolver:基础实现,有核心逻辑方法:checkGenericTypeMatch(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor),


作用为:根据给定的候选bean定义,将给定的依赖类型与其泛型类型信息匹配。(这就是泛型依赖注入的核心匹配逻辑,所以这列其实也是Spring4.0后才推出来的)

  protected boolean checkGenericTypeMatch(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
    ResolvableType dependencyType = descriptor.getResolvableType();
    if (dependencyType.getType() instanceof Class) {
      // No generic type -> we know it's a Class type-match, so no need to check again.
      return true;
    }
    ResolvableType targetType = null;
    boolean cacheType = false;
    RootBeanDefinition rbd = null;
    if (bdHolder.getBeanDefinition() instanceof RootBeanDefinition) {
      rbd = (RootBeanDefinition) bdHolder.getBeanDefinition();
    }
    if (rbd != null) {
      targetType = rbd.targetType;
      if (targetType == null) {
        cacheType = true;
        // First, check factory method return type, if applicable
        targetType = getReturnTypeForFactoryMethod(rbd, descriptor);
        if (targetType == null) {
          RootBeanDefinition dbd = getResolvedDecoratedDefinition(rbd);
          if (dbd != null) {
            targetType = dbd.targetType;
            if (targetType == null) {
              targetType = getReturnTypeForFactoryMethod(dbd, descriptor);
            }
          }
        }
      }
    }
    if (targetType == null) {
      // Regular case: straight bean instance, with BeanFactory available.
      if (this.beanFactory != null) {
        Class<?> beanType = this.beanFactory.getType(bdHolder.getBeanName());
        if (beanType != null) {
          targetType = ResolvableType.forClass(ClassUtils.getUserClass(beanType));
        }
      }
      // Fallback: no BeanFactory set, or no type resolvable through it
      // -> best-effort match against the target class if applicable.
      if (targetType == null && rbd != null && rbd.hasBeanClass() && rbd.getFactoryMethodName() == null) {
        Class<?> beanClass = rbd.getBeanClass();
        if (!FactoryBean.class.isAssignableFrom(beanClass)) {
          targetType = ResolvableType.forClass(ClassUtils.getUserClass(beanClass));
        }
      }
    }
    if (targetType == null) {
      return true;
    }
    if (cacheType) {
      rbd.targetType = targetType;
    }
    if (descriptor.fallbackMatchAllowed() && targetType.hasUnresolvableGenerics()) {
      return true;
    }
    // Full check for complex generic type match...
    return dependencyType.isAssignableFrom(targetType);
  }
  @Nullable
  protected RootBeanDefinition getResolvedDecoratedDefinition(RootBeanDefinition rbd) {
    BeanDefinitionHolder decDef = rbd.getDecoratedDefinition();
    if (decDef != null && this.beanFactory instanceof ConfigurableListableBeanFactory) {
      ConfigurableListableBeanFactory clbf = (ConfigurableListableBeanFactory) this.beanFactory;
      if (clbf.containsBeanDefinition(decDef.getBeanName())) {
        BeanDefinition dbd = clbf.getMergedBeanDefinition(decDef.getBeanName());
        if (dbd instanceof RootBeanDefinition) {
          return (RootBeanDefinition) dbd;
        }
      }
    }
    return null;
  }
  @Nullable
  protected ResolvableType getReturnTypeForFactoryMethod(RootBeanDefinition rbd, DependencyDescriptor descriptor) {
    // Should typically be set for any kind of factory method, since the BeanFactory
    // pre-resolves them before reaching out to the AutowireCandidateResolver...
    ResolvableType returnType = rbd.factoryMethodReturnType;
    if (returnType == null) {
      Method factoryMethod = rbd.getResolvedFactoryMethod();
      if (factoryMethod != null) {
        returnType = ResolvableType.forMethodReturnType(factoryMethod);
      }
    }
    if (returnType != null) {
      Class<?> resolvedClass = returnType.resolve();
      if (resolvedClass != null && descriptor.getDependencyType().isAssignableFrom(resolvedClass)) {
        // Only use factory method metadata if the return type is actually expressive enough
        // for our dependency. Otherwise, the returned instance type may have matched instead
        // in case of a singleton instance having been registered with the container already.
        return returnType;
      }
    }
    return null;
  }


QualifierAnnotationAutowireCandidateResolver:对@Qualifier的解析,功能是将qualifier注解要自动绑定的field或者参数和bean definition qualifier相匹配。同时也支持通过@value注解来绑定表达式的值。另外还支持JSR-330的javax.inject.Qualifier注解


ContextAnnotationAutowireCandidateResolver:对@Lazy的解析


@Required:依赖检查;@Autowired:自动装配(可完全代替基于xml的装配)

@Value(value = “SpEL表达式”) 或者 @Value(value = “#{message}”)

@Qualifier:限定描述符,用于细粒度选择候选者

@Inject:等价于默认的@Autowired,只是没有required属性(支持@Primary)


QualifierAnnotationAutowireCandidateResolver#getSuggestedValue:处理标注了@Value注解的情况

  private Class<? extends Annotation> valueAnnotationType = Value.class;
  // 拿到value注解的这个属性(若标注有@Value注解的话)
  @Override
  @Nullable
  public Object getSuggestedValue(DependencyDescriptor descriptor) {
    Object value = findValue(descriptor.getAnnotations());
    if (value == null) {
      // 看看方法有没有标注
      MethodParameter methodParam = descriptor.getMethodParameter();
      if (methodParam != null) {
        value = findValue(methodParam.getMethodAnnotations());
      }
    }
    return value;
  }
  /**
   * Determine a suggested value from any of the given candidate annotations.
   */
  @Nullable
  protected Object findValue(Annotation[] annotationsToSearch) {
    // 寻找到@Value注解的value属性值
    AnnotationAttributes attr = AnnotatedElementUtils.getMergedAnnotationAttributes(
        AnnotatedElementUtils.forAnnotations(annotationsToSearch), this.valueAnnotationType);
    if (attr != null) {
      return extractValue(attr);
    }
    return null;
  }
  /**
   * Extract the value attribute from the given annotation.
   * @since 4.3
   */
  protected Object extractValue(AnnotationAttributes attr) {
    Object value = attr.get(AnnotationUtils.VALUE);
    if (value == null) {
      throw new IllegalStateException("Value annotation must have a value attribute");
    }
    return value;
  }



相关文章
|
2月前
|
负载均衡 算法 Java
除了 Ribbon,Spring Cloud 中还有哪些负载均衡组件?
这些负载均衡组件各有特点,在不同的场景和需求下,可以根据项目的具体情况选择合适的负载均衡组件来实现高效、稳定的服务调用。
108 5
|
4月前
|
XML 缓存 Java
spring源码剖析-spring-beans(内部核心组件,BeanDefinition的注册,BeanWapper创建)
spring源码剖析-spring-beans(内部核心组件,BeanDefinition的注册,BeanWapper创建)
63 10
|
4月前
|
XML 存储 Java
spring源码刨析-spring-beans(内部核心组件,beanDefinition加载过程)
spring源码刨析-spring-beans(内部核心组件,beanDefinition加载过程)
|
5月前
|
人工智能 自然语言处理 Java
Spring AI,Spring团队开发的新组件,Java工程师快来一起体验吧
文章介绍了Spring AI,这是Spring团队开发的新组件,旨在为Java开发者提供易于集成的人工智能API,包括机器学习、自然语言处理和图像识别等功能,并通过实际代码示例展示了如何快速集成和使用这些AI技术。
Spring AI,Spring团队开发的新组件,Java工程师快来一起体验吧
|
5月前
|
Java Spring
Spring的AOP组件详解
该文章主要介绍了Spring AOP(面向切面编程)组件的实现原理,包括Spring AOP的基础概念、动态代理模式、AOP组件的实现以及Spring选择JDK动态代理或CGLIB动态代理的依据。
Spring的AOP组件详解
|
5月前
|
Java 开发工具 Spring
【Azure 事件中心】azure-spring-cloud-stream-binder-eventhubs客户端组件问题, 实践消息非顺序可达
【Azure 事件中心】azure-spring-cloud-stream-binder-eventhubs客户端组件问题, 实践消息非顺序可达
|
6月前
|
安全 前端开发 Java
Java技术栈中的核心组件:Spring框架
Java作为一门成熟的编程语言,其生态系统拥有众多强大的组件和框架,其中Spring框架无疑是Java技术栈中最闪耀的明星之一。Spring框架为Java开发者提供了一套全面的编程和配置模型,极大地简化了企业级应用的开发流程。
74 1
|
7月前
|
NoSQL 前端开发 Java
技术笔记:springboot分布式锁组件spring
技术笔记:springboot分布式锁组件spring
63 1
|
7月前
|
Java API 数据安全/隐私保护
在Spring Boot中,过滤器(Filter)是一种非常有用的组件
在Spring Boot中,过滤器(Filter)是一种非常有用的组件
93 6
|
7月前
|
负载均衡 前端开发 Java
OpenFeign:Spring Cloud声明式服务调用组件
该文本是关于OpenFeign在Spring Cloud中的使用的问答总结。涉及的问题包括:OpenFeign是什么,Feign与OpenFeign的区别,如何使用OpenFeign进行远程服务调用,OpenFeign的超时控制以及日志增强。OpenFeign被描述为Spring官方的声明式服务调用和负载均衡组件,它支持使用注解进行接口定义和服务调用,如@FeignClient和@EnableFeignClients。OpenFeign与Feign的主要区别在于OpenFeign支持Spring MVC注解。超时控制通过Ribbon进行设置,默认超时时间为1秒。