Spring中的AutowireCandidateResolver的具體使用詳解
阿新 • • 發佈:2020-04-24
介面定義
用於推斷一個特定的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<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 方法。
到此這篇關於Spring中的AutowireCandidateResolver的具體使用詳解的文章就介紹到這了,更多相關Spring AutowireCandidateResolver內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!