您的位置:首页技术文章
文章详情页

Spring中的AutowireCandidateResolver的具体使用详解

【字号: 日期:2023-09-09 13:15:51浏览:11作者:猪猪

接口定义

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

public interface AutowireCandidateResolver {// 默认情况下直接根据bd中的定义返回,如果没有进行特殊配置的话为truedefault 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注解 // 默认情况下返回falsedefault boolean hasQualifier(DependencyDescriptor descriptor) {return false;} // QualifierAnnotationAutowireCandidateResolver做了实现 // 获取一个该依赖一个建议的值@Nullabledefault Object getSuggestedValue(DependencyDescriptor descriptor) {return null;} // 对某个依赖我们想要延迟注入,但是在创建Bean的过程中这个依赖又是必须的 // 通过下面这个方法就能为延迟注入的依赖先生成一个代理注入到bean中@Nullabledefault Object getLazyResolutionProxyIfNecessary(DependencyDescriptor descriptor, @Nullable String beanName) {return null;}}

继承关系

Spring中的AutowireCandidateResolver的具体使用详解

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

SimpleAutowireCandidateResolver

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

public class SimpleAutowireCandidateResolver implements AutowireCandidateResolver {@Overridepublic boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {return bdHolder.getBeanDefinition().isAutowireCandidate();}@Overridepublic boolean isRequired(DependencyDescriptor descriptor) {return descriptor.isRequired();}@Override@Nullablepublic Object getSuggestedValue(DependencyDescriptor descriptor) {return null;}@Override@Nullablepublic Object getLazyResolutionProxyIfNecessary(DependencyDescriptor descriptor, @Nullable String beanName) {return null;}}

GenericTypeAwareAutowireCandidateResolver

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

public class GenericTypeAwareAutowireCandidateResolver extends SimpleAutowireCandidateResolverimplements BeanFactoryAware {@Nullableprivate BeanFactory beanFactory;@Overridepublic void setBeanFactory(BeanFactory beanFactory) {this.beanFactory = beanFactory;}@Nullableprotected final BeanFactory getBeanFactory() {return this.beanFactory;}@Overridepublic boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {if (!super.isAutowireCandidate(bdHolder, descriptor)) {// 如果bd中已经配置了这个bean不做为依赖进行注入的话,直接返回falsereturn 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.}}// .......@Overridepublic 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@Nullablepublic 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注解@Nullableprotected 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@Nullablepublic 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();// 创建了一个TargetSourceTargetSource ts = new TargetSource() {@Overridepublic Class<?> getTargetClass() {return descriptor.getDependencyType();}@Overridepublic boolean isStatic() {return false;} // target是我们实际想要使用的对象,如果不进行延迟处理,那么注入到bean中的应该就是这个对象 // 但是因为要进行延迟注入依赖,所有会向外暴露一个TargetSource,这个TargetSource的目标为实际想要使用的对象,生成代理时会基于TargetSource进行生成。在运行期间(完成注入后)我们使用这个延迟处理的依赖时实际调用的会是target中的方法。@Overridepublic 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;}@Overridepublic 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 方法。

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

标签: Spring
相关文章: