谈谈 Spring 中的 AutowireCandidateResolver

点击上方  IT牧场 ,选择  置顶或者星标

技术干货每日送达!

接口定义

用于推断一个特定的beanDefinition是否能作为指定依赖的候选者的策略接口

public interface AutowireCandidateResolver {
 // 默认情况下直接根据bd中的定义返回,如果没有进行特殊配置的话为true
 default boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
  return bdHolder.getBeanDefinition().isAutowireCandidate();
 }
 
    // 指定的依赖是否是必要的
 default boolean isRequired(DependencyDescriptor descriptor) {
  return descriptor.isRequired();
 }
 
    // QualifierAnnotationAutowireCandidateResolver做了实现,判断是否有@Qualifier注解
    // 一共有两种注解:
    // 1.Spring内置的@Qualifier注解,org.springframework.beans.factory.annotation.Qualifier
    // 2.添加了JSR-330相关依赖,javax.inject.Qualifier注解
    // 默认情况下返回false
 default boolean hasQualifier(DependencyDescriptor descriptor) {
  return false;
 }
 
    // QualifierAnnotationAutowireCandidateResolver做了实现
    // 获取一个该依赖一个建议的值
 @Nullable
 default Object getSuggestedValue(DependencyDescriptor descriptor) {
  return null;
 }
 
    // 对某个依赖我们想要延迟注入,但是在创建Bean的过程中这个依赖又是必须的
    // 通过下面这个方法就能为延迟注入的依赖先生成一个代理注入到bean中
 @Nullable
 default Object getLazyResolutionProxyIfNecessary(DependencyDescriptor descriptor, @Nullable String beanName) {
  return null;
 }

}

继承关系

谈谈 Spring 中的 AutowireCandidateResolver

可以看到继承关系都是单层的,我们就一个一个往下看

SimpleAutowireCandidateResolver

相比于接口没有什么区别,实现也就是父接口中的默认实现,一般也不会使用这个类

public class SimpleAutowireCandidateResolver implements AutowireCandidateResolver {

 @Override
 public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
  return bdHolder.getBeanDefinition().isAutowireCandidate();
 }

 @Override
 public boolean isRequired(DependencyDescriptor descriptor) {
  return descriptor.isRequired();
 }

 @Override
 @Nullable
 public Object getSuggestedValue(DependencyDescriptor descriptor) {
  return null;
 }

 @Override
 @Nullable
 public Object getLazyResolutionProxyIfNecessary(DependencyDescriptor descriptor, @Nullable String beanName) {
  return null;
 }

}

GenericTypeAwareAutowireCandidateResolver

额外增加了对泛型的处理能力

public class GenericTypeAwareAutowireCandidateResolver extends SimpleAutowireCandidateResolver
  implements BeanFactoryAware {

 @Nullable
 private BeanFactory beanFactory;


 @Override
 public void setBeanFactory(BeanFactory beanFactory) {
  this.beanFactory = beanFactory;
 }

 @Nullable
 protected final BeanFactory getBeanFactory() {
  return this.beanFactory;
 }


 @Override
 public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
  if (!super.isAutowireCandidate(bdHolder, descriptor)) {
   // 如果bd中已经配置了这个bean不做为依赖进行注入的话,直接返回false
   return false;
  }
        // 检查泛型是否匹配
  return checkGenericTypeMatch(bdHolder, descriptor);
 }

}

QualifierAnnotationAutowireCandidateResolver

增加了对@Qualifier注解以及@Value注解的处理能力

public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwareAutowireCandidateResolver {

 private final Set<Class<? extends Annotation>> qualifierTypes = new LinkedHashSet<>(2);
 // @Value注解
 private Class<? extends Annotation> valueAnnotationType = Value.class;
 
    // @Qualifier注解
 @SuppressWarnings("unchecked")
 public QualifierAnnotationAutowireCandidateResolver() {
  this.qualifierTypes.add(Qualifier.class);
  try {
   this.qualifierTypes.add((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Qualifier",
       QualifierAnnotationAutowireCandidateResolver.class.getClassLoader()));
  }
  catch (ClassNotFoundException ex) {
   // JSR-330 API not available - simply skip.
  }
 }

 // .......

 @Override
 public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
        // 类型上已经匹配了
  boolean match = super.isAutowireCandidate(bdHolder, descriptor);
  if (match) {
            // 还需要判断是否满足@Qualifier注解的要求
   match = checkQualifiers(bdHolder, descriptor.getAnnotations());
   if (match) {
    MethodParameter methodParam = descriptor.getMethodParameter();
    if (methodParam != null) {
     Method method = methodParam.getMethod();
     if (method == null || void.class == method.getReturnType()) {
      match = checkQualifiers(bdHolder, methodParam.getMethodAnnotations());
     }
    }
   }
  }
  return match;
 }

 // .....
 
    // 是否是@Qualifier注解
 protected boolean isQualifier(Class<? extends Annotation> annotationType) {
  for (Class<? extends Annotation> qualifierType : this.qualifierTypes) {
   if (annotationType.equals(qualifierType) || annotationType.isAnnotationPresent(qualifierType)) {
    return true;
   }
  }
  return false;
 }
 
 @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;
 }
 
    
    // 查找@Value注解
 @Nullable
 protected Object findValue(Annotation[] annotationsToSearch) {
  if (annotationsToSearch.length > 0) {   
   AnnotationAttributes attr = AnnotatedElementUtils.getMergedAnnotationAttributes(
     AnnotatedElementUtils.forAnnotations(annotationsToSearch), this.valueAnnotationType);
   if (attr != null) {
    return extractValue(attr);
   }
  }
  return null;
 }
 
    // 获取@Value注解中的值
 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;
 }

}

ContextAnnotationAutowireCandidateResolver

这个类是最底层的子类,集成了所有的方法,并且额外提供了对依赖进行延迟处理的能力

public class ContextAnnotationAutowireCandidateResolver extends QualifierAnnotationAutowireCandidateResolver {
 
    // 如果依赖需要进行延迟处理,那么构建一个代理对象先注入到bean中,不会直接去创建依赖对象
 @Override
 @Nullable
 public Object getLazyResolutionProxyIfNecessary(DependencyDescriptor descriptor, @Nullable String beanName) {
  return (isLazy(descriptor) ? buildLazyResolutionProxy(descriptor, beanName) : null);
 }
 
    // 依赖是否需要延迟处理
 protected boolean isLazy(DependencyDescriptor descriptor) {
  for (Annotation ann : descriptor.getAnnotations()) {
   Lazy lazy = AnnotationUtils.getAnnotation(ann, Lazy.class);
   if (lazy != null && lazy.value()) {
    return true;
   }
  }
  MethodParameter methodParam = descriptor.getMethodParameter();
  if (methodParam != null) {
   Method method = methodParam.getMethod();
   if (method == null || void.class == method.getReturnType()) {
    Lazy lazy = AnnotationUtils.getAnnotation(methodParam.getAnnotatedElement(), Lazy.class);
    if (lazy != null && lazy.value()) {
     return true;
    }
   }
  }
  return false;
 }
 
    // 构建延迟处理的代理对象
 protected Object buildLazyResolutionProxy(final DependencyDescriptor descriptor, final @Nullable String beanName) {
  final DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) getBeanFactory();
        
        // 创建了一个TargetSource
  TargetSource ts = new TargetSource() {
   @Override
   public Class<?> getTargetClass() {
    return descriptor.getDependencyType();
   }
   @Override
   public boolean isStatic() {
    return false;
   }
            // target是我们实际想要使用的对象,如果不进行延迟处理,那么注入到bean中的应该就是这个对象
            // 但是因为要进行延迟注入依赖,所有会向外暴露一个TargetSource,这个TargetSource的目标为实际想要使用的对象,生成代理时会基于TargetSource进行生成。在运行期间(完成注入后)我们使用这个延迟处理的依赖时实际调用的会是target中的方法。
   @Override
   public Object getTarget() {
    Object target = beanFactory.doResolveDependency(descriptor, beanName, null, null);
    if (target == null) {
     Class<?> type = getTargetClass();
     if (Map.class == type) {
      return Collections.emptyMap();
     }
     else if (List.class == type) {
      return Collections.emptyList();
     }
     else if (Set.class == type || Collection.class == type) {
      return Collections.emptySet();
     }
     throw new NoSuchBeanDefinitionException(descriptor.getResolvableType(),
       "Optional dependency not present for lazy injection point");
    }
    return target;
   }
   @Override
   public void releaseTarget(Object target) {
   }
  };
        
        // 使用ProxyFactory,给TargetSource生成一个代理
  ProxyFactory pf = new ProxyFactory();
  pf.setTargetSource(ts);
  Class<?> dependencyType = descriptor.getDependencyType();
        // 如果依赖的类型是一个接口,需要让代理类也实现这个接口
  if (dependencyType.isInterface()) {
   pf.addInterface(dependencyType);
  }
        // 生成代理
  return pf.getProxy(beanFactory.getBeanClassLoader());
 }

}

总结

  • SimpleAutowireCandidateResolver:单纯的将接口变成了可实例化的类,方法实现跟接口保持一致

  • GenericTypeAwareAutowireCandidateResolver:判断泛型是否匹配,支持泛型依赖注入(From Spring4.0)

  • QualifierAnnotationAutowireCandidateResolver :处理 @Qualifier 和 @Value 注解

  • ContextAnnotationAutowireCandidateResolver :处理依赖级别的 @Lazy 注解,重写了getLazyResolutionProxyIfNecessary 方法。

干货分享

最近将个人学习笔记整理成册,使用PDF分享。关注我,回复如下代码,即可获得百度盘地址,无套路领取!

001:《Java并发高并发解决方案》学习笔记; 002:《深入JVM内核——原理、诊断与优化》学习笔记; 003:《Java面试宝典》 004:《Docker开源书》 005:《Kubernetes开源书》 006:《DDD速成(领域驱动设计速成)》 007: 全部 008: 加技术群讨论

近期热文

关注我

谈谈 Spring 中的 AutowireCandidateResolver

喜欢就点个"在看"呗^_^

原文 

http://mp.weixin.qq.com/s?__biz=MzI4ODQ3NjE2OA==&mid=2247487522&idx=2&sn=f2d78597eb2b26f2592ea3558ef40c68

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » 谈谈 Spring 中的 AutowireCandidateResolver

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址