当前位置:  首页  >  PHP资讯  >  业界资讯

Spring中的AutowireCandidateResolver的具体使用详解

这篇文章主要介绍了Spring中的AutowireCandidateResolver的具体使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

接口定义

用于推断一个特定的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; } }

继承关系

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

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> qualifierTypes = new LinkedHashSet<>(2); // @Value注解 private Class<&#63; extends Annotation> valueAnnotatiOnType= Value.class; // @Qualifier注解 @SuppressWarnings("unchecked") public QualifierAnnotationAutowireCandidateResolver() { this.qualifierTypes.add(Qualifier.class); try { this.qualifierTypes.add((Class<&#63; 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<&#63; extends Annotation> annotationType) { for (Class<&#63; 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) &#63; 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<&#63;> 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<&#63;> 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<&#63;> 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 方法。

到此这篇关于Spring中的AutowireCandidateResolver的具体使用详解的文章就介绍到这了,更多相关Spring AutowireCandidateResolver内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

内容推荐:免费高清PNG素材下载
吐了个 "CAO" !
扫码关注 PHP1 官方微信号
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved PHP1.CN 第一PHP社区 版权所有 京ICP备19059560号-4