Spring中的AutowireCandidateResolver的具体使用详解

网友投稿 378 2022-12-08


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(DependencyDescripthttp://or 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 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.getAnhttp://notations());

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:单纯的将接口变成了可实例化的类http://,方法实现跟接口保持一致

GenericTypeAwareAutowireCandidateResolver: 判断泛型是否匹配,支持泛型依赖注入(From Spring4.0)

QualifierAnnotationAutowireCandidateResolver :处理 @Qualifier 和 @Value 注解

ContextAnnotationAutowireCandidateResolver :处理依赖级别的 @Lazy 注解,重写了getLazyResolutionProxyIfNecessary 方法。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:java实现扫雷游戏
下一篇:Thymeleaf对象的使用之基本对象实例解析
相关文章

 发表评论

暂时没有评论,来抢沙发吧~