Spring依赖注入
2023-02-05 19:07:06 0 举报
Spring依赖注入超详细流程图解
作者其他创作
大纲/内容
false
super.isAutowireCandidate()
true
for (String propertyName : propertyNames)
遍历是否完成
是否有缓存,第一次是没有缓存的if (this.cached)
return result
break
ann != null
font color=\"#323232\
GenericTypeAwareAutowireCandidateResolver.isAutowireCandidate()
拿到类型转换器TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
从根据类型匹配的Bean中拿到名字也匹配的BeaninstanceCandidate = matchingBeans.get(autowiredBeanName);
result.add(beanName);
查找类中字段上的注解,并添加到currElements ReflectionUtils.doWithLocalFields
当前InjectedElement是否是字段if (this.isField)
得到属性描述器PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
return;
return result
获取注解上的required 属性boolean required = determineRequiredStatus(ann);
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
处理@Priority注解,Priority上值越小优先级越高,span style=\"font-size: inherit;\
查找创建metadata = buildAutowiringMetadata(clazz);
获取方法信息Method method = (Method) this.member;
int i = 0;
判断required是否==trueisRequired(descriptor)
得到类型Class<?> autowiringType = classObjectEntry.getKey();
lbf instanceof HierarchicalBeanFactoryHierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf
方法结束
beanNamesForTypeIncludingAncestors(font color=\"#323232\
if (pvs == null) { pvs = mbd.getPropertyValues(); }
value != null
查找Bean的时候有可能依赖的Bean还没有创建
primaryCandidate != null
return resource;
for (Method method : methods)
return candidateName
获取InjectedElement记录的字段信息Field field = (Field) this.member;
是否是静态字段Modifier.isStatic(field.getModifiers())
hasInstAwareBpps
是否遍历完所有方法methods
单例池或者beanDefinitionMap中是否存在这个beanNamecontainsBean(propertyName)
return primaryCandidate
resource == nul
! isVisibilityBridgeMethodPair
根据名字是否能找到Beanfactory.containsBean(name)
Value是否是ClassinstanceCandidate instanceof Class
查找类中方法上的注解,并添加到currElements ReflectionUtils.doWithLocalMethods
建立缓存
return multipleBeans
将查找到的currElementsspan style=\"font-size: inherit;\
return StringUtils.toStringArray(result);
循环this.injectedElements
该方法调用时机:在通过构造方法创建Bean对象之后,Bean的实例化后置处理器之前
return null
递归
再次遍历candidateNames
if (multipleBeans != null)
在依赖注入前先调用bean的后置处理器实例化后方法ibp.postProcessAfterInstantiation
inject()
int argumentCount = method.getParameterCount(); arguments = new Object[argumentCount];
处理@Resource注解CommonAnnotationBeanPostProcessorfont color=\"#323232\
ReflectionUtils.makeAccessible(field);
mc.doWith(method);
处理${}站位String strVal = resolveEmbeddedValue((String) value);
得到当前类的父类targetClass = targetClass.getSuperclass();
查找创建metadata = buildAutowiringMetadata(clazz);
是否是Object类Object.class != pd.getPropertyType()
类型是否匹配autowiringType.isAssignableFrom(requiredType)
InjectedElement:类中标志有@Autowire、@Value、@Inject的字段或方法
根据类型是否查找出了多个BeanmatchingBeans.size() > 1
ann = findAutowiredAnnotation(bridgedMethod);
找到桥接方法Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
处理@Autowire @Value注解AutowiredAnnotationBeanPostProcessorfont color=\"#323232\
required 注解是否为trueisRequired(descriptor)
非可见性桥接方法不做处理return:
elementsToIterate.isEmpty()
拿到Bean的名字和ValueautowiredBeanName = entry.getKey(); instanceCandidate = entry.getValue();
首先从缓存中获取,缓存中获取不到真正去查找创建InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
String candidateName = entry.getKey(); Object beanInstance = entry.getValue();
InjectedElement数组:elementsToIterate
根据名字查找依赖Beanfont color=\"#323232\
获取InjectedElement记录的方法信息Method method = (Method) this.member;
ann != null
查找出来的候选依赖注入beanNamecandidateNames
处理字段AutowiredFieldElement.inject()
candidates.entrySet()是否遍历完
resolvedAutowireMode == AUTOWIRE_BY_NAME
return result;
resolvableDependencies.entrySet()是否遍历完成或者是找到匹配的属性
Spring属性直接实现,需要set方法
if (result == null)
抛异常throw new NoSuchBeanDefinitionException
return match
查找InjectedElement的核心span style=\"font-size: inherit;\
QualifierAnnotationAutowireCandidateResolver.isAutowireCandidate()
向上查找:除了查找类本身的注解外,还需要向上查找父类中的注解while (targetClass != null && targetClass != Object.class);
resolvedAutowireMode == AUTOWIRE_BY_TYPE
Collection<InjectedElement> elementsToIterate = (checkedElements != null ? checkedElements : this.injectedElements);
判断@Resource上是否指定了名字element.isDefaultName
result instanceof NullBean
autowiredBeanName == null
处理BeanDefinition,通过后置处理器方式实现applyMergedBeanDefinitionPostProcessors()
for (InjectedElement element : elementsToIterate)
缓存中获取对象arguments = resolveCachedArguments(beanName);
beanDefinition上手动添加了属性值到PropertyValuesPropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
是否遍历完所有字段
结束
遍历elementsToIterate
扫描查找InjectedElement并缓存起来备用
fc.doWith(field);
priorityCandidate != null
获取类上的所有字段getDeclaredFields(clazz)
处理autowireCandidate属性 true/falsereturn bdHolder.getBeanDefinition().isAutowireCandidate();
方法参数可以是多个Object[] arguments;
遍历propertyNames
遍历所有字段
根据类型查找Beanfont color=\"#323232\
ReflectionUtils.makeAccessible(method);
if (matchFound)
ann = findAutowiredAnnotation(field);
final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
得到属性注入方式 byType或者byNameint resolvedAutowireMode = mbd.getResolvedAutowireMode();
elementsToIterate是否遍历完成
拿到依赖类型Class<?> requiredType = descriptor.getDependencyType();
筛选可以注入的Beanfont color=\"#323232\
return null
处理@Value注解,拿到@Value的值Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
i < arguments.length;
return priorityCandidate
如果指定了名字,直接根据名字getBean
依赖类型Class<?> type = descriptor.getDependencyType();
处理方法AutowiredMethodElement.inject()
得到依赖对象Beanreturn beanFactory.getBean(beanName);
遍历candidateNames依次判断
SimpleAutowireCandidateResolver.isAutowireCandidate()
autowiredArgument != null
遍历candidates.entrySet()
非自己的依赖类型都不匹配,这时需要考虑自己依赖注入自己result.isEmpty() && !multiple
如:泛型类生成的字节码文件中除本身方法外,还会生成一个桥接方法,这个方法是不需要的
是否有缓存,第一次是没有缓存的if (this.cached)
for (Field field : getDeclaredFields(clazz))
遍历所有方法
为什么放到首位:维护父子调用关系
是否是静态方法Modifier.isStatic(method.getModifiers())
是否存在实例化的Bean的后置处理器boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
找不到抛异常throw new NoSuchBeanDefinitionException
resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE
doGetBeanNamesForType()
bdp具体实现类是:AutowiredAnnotationBeanPostProcessor/CommonAnnotationBeanPostProcessor它们查找InjectedElement方式类似,这里以Autowired流程为例
获取字段信息Field field = (Field) this.member;
matchingBeans.isEmpty()
Object result = instanceCandidate;
抛异常throw new NoSuchBeanDefinitionException
0 条评论
回复 删除
下一页