Spring中的AutowireCandidateResolver的具體使用詳解
接口定義
用于推斷一個特定的beanDefinition是否能作為指定依賴的候選者的策略接口
public interface AutowireCandidateResolver { // 默認(rèn)情況下直接根據(jù)bd中的定義返回,如果沒有進(jìn)行特殊配置的話為true default boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) { return bdHolder.getBeanDefinition().isAutowireCandidate(); } // 指定的依賴是否是必要的 default boolean isRequired(DependencyDescriptor descriptor) { return descriptor.isRequired(); } // QualifierAnnotationAutowireCandidateResolver做了實現(xiàn),判斷是否有@Qualifier注解 // 一共有兩種注解: // 1.Spring內(nèi)置的@Qualifier注解,org.springframework.beans.factory.annotation.Qualifier // 2.添加了JSR-330相關(guān)依賴,javax.inject.Qualifier注解 // 默認(rèn)情況下返回false default boolean hasQualifier(DependencyDescriptor descriptor) { return false; } // QualifierAnnotationAutowireCandidateResolver做了實現(xiàn) // 獲取一個該依賴一個建議的值 @Nullable default Object getSuggestedValue(DependencyDescriptor descriptor) { return null; } // 對某個依賴我們想要延遲注入,但是在創(chuàng)建Bean的過程中這個依賴又是必須的 // 通過下面這個方法就能為延遲注入的依賴先生成一個代理注入到bean中 @Nullable default Object getLazyResolutionProxyIfNecessary(DependencyDescriptor descriptor, @Nullable String beanName) { return null; } }
繼承關(guān)系
可以看到繼承關(guān)系都是單層的,我們就一個一個往下看
SimpleAutowireCandidateResolver
相比于接口沒有什么區(qū)別,實現(xiàn)也就是父接口中的默認(rèn)實現(xiàn),一般也不會使用這個類
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中已經(jīng)配置了這個bean不做為依賴進(jìn)行注入的話,直接返回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) { // 類型上已經(jīng)匹配了 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
這個類是最底層的子類,集成了所有的方法,并且額外提供了對依賴進(jìn)行延遲處理的能力
public class ContextAnnotationAutowireCandidateResolver extends QualifierAnnotationAutowireCandidateResolver { // 如果依賴需要進(jìn)行延遲處理,那么構(gòu)建一個代理對象先注入到bean中,不會直接去創(chuàng)建依賴對象 @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; } // 構(gòu)建延遲處理的代理對象 protected Object buildLazyResolutionProxy(final DependencyDescriptor descriptor, final @Nullable String beanName) { final DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) getBeanFactory(); // 創(chuàng)建了一個TargetSource TargetSource ts = new TargetSource() { @Override public Class<?> getTargetClass() { return descriptor.getDependencyType(); } @Override public boolean isStatic() { return false; } // target是我們實際想要使用的對象,如果不進(jìn)行延遲處理,那么注入到bean中的應(yīng)該就是這個對象 // 但是因為要進(jìn)行延遲注入依賴,所有會向外暴露一個TargetSource,這個TargetSource的目標(biāo)為實際想要使用的對象,生成代理時會基于TargetSource進(jìn)行生成。在運(yùn)行期間(完成注入后)我們使用這個延遲處理的依賴時實際調(diào)用的會是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(); // 如果依賴的類型是一個接口,需要讓代理類也實現(xiàn)這個接口 if (dependencyType.isInterface()) { pf.addInterface(dependencyType); } // 生成代理 return pf.getProxy(beanFactory.getBeanClassLoader()); } }
總結(jié)
- SimpleAutowireCandidateResolver:單純的將接口變成了可實例化的類,方法實現(xiàn)跟接口保持一致
- GenericTypeAwareAutowireCandidateResolver: 判斷泛型是否匹配,支持泛型依賴注入(From Spring4.0)
- QualifierAnnotationAutowireCandidateResolver :處理 @Qualifier 和 @Value 注解
- ContextAnnotationAutowireCandidateResolver :處理依賴級別的 @Lazy 注解,重寫了getLazyResolutionProxyIfNecessary 方法。
到此這篇關(guān)于Spring中的AutowireCandidateResolver的具體使用詳解的文章就介紹到這了,更多相關(guān)Spring AutowireCandidateResolver內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springboot如何讀取配置文件(application.yml)中的屬性值
本篇文章主要介紹了springboot如何讀取配置文件(application.yml)中的屬性值,具有一定的參考價值,有興趣的小伙伴可以了解一下2017-04-04springmvc實現(xiàn)跨服務(wù)器文件上傳功能
這篇文章主要為大家詳細(xì)介紹了springmvc實現(xiàn)跨服務(wù)器文件上傳功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-08-08Java 守護(hù)線程_動力節(jié)點(diǎn)Java學(xué)院整理
Java語言機(jī)制是構(gòu)建在JVM的基礎(chǔ)之上的,意思是Java平臺把操作系統(tǒng)的底層給屏蔽起來,所以它可以在它自己的虛擬的平臺里面構(gòu)造出對自己有利的機(jī)制,而語言或者說平臺的設(shè)計者多多少少是收到Unix思想的影響,而守護(hù)線程機(jī)制又是對JVM這樣的平臺湊合,于是守護(hù)線程應(yīng)運(yùn)而生2017-05-05Mybatis通過數(shù)據(jù)庫表自動生成實體類和xml映射文件
這篇文章主要介紹了Mybatis通過數(shù)據(jù)庫表自動生成實體類和xml映射文件的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07idea中g(shù)it如何刪除commit提交的log信息
這篇文章主要介紹了idea中g(shù)it如何刪除commit提交的log信息問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07java實現(xiàn)切圖并且判斷圖片是不是純色/彩色圖片
本篇文章主要介紹了java實現(xiàn)切圖并且判斷圖片是否是純色/彩色圖片,具有一定的參考價值,有興趣的可以了解一下2017-08-08