前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >谈谈 Spring 中的 AutowireCandidateResolver

谈谈 Spring 中的 AutowireCandidateResolver

作者头像
用户1516716
发布2020-07-16 15:48:04
3850
发布2020-07-16 15:48:04
举报
文章被收录于专栏:A周立SpringCloud

接口定义

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

代码语言:javascript
复制
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;
 }

}

继承关系

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

SimpleAutowireCandidateResolver

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

代码语言:javascript
复制
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

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

代码语言:javascript
复制
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注解的处理能力 ”

代码语言:javascript
复制
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

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

代码语言:javascript
复制
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 方法。
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-07-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 IT牧场 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 继承关系
    • SimpleAutowireCandidateResolver
      • GenericTypeAwareAutowireCandidateResolver
        • QualifierAnnotationAutowireCandidateResolver
          • ContextAnnotationAutowireCandidateResolver
          • 总结
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档