DefaultListableBeanFactory的doResolveDependency解析依赖
继续上篇的,如果是我们自己定义的类型的参数,没有懒加载注解的,就会进行解析。
首先看BeanFactiry
是否有添加快捷方式,一般没有,除非子类继承扩展,然后看是否有注解方法设置的参数的值,有的话就设置处理。否则的话就判断是否是多个bean
的注入,比如参数类型是集合。最后才是获取自动装配类型的对象findAutowireCandidates
,如果找到多个的话,会进行优先级来选取,然后进行装配类型对象的创建,这里的创建又是一个getBean
的过程,但是也可能是直接获取,一般来说是主要看工厂方法的定义顺序,因为内部可以用了ASM
处理,但是如果有重名的,就乱序了,具体为什么不行可以看ConfigurationClassParser
的retrieveBeanMethodMetadata
方法,不过影响也不大,反正都能自动装配好。创建好了再判断类型是否匹配,最后返回。下面我们来分析几个主要的方法,主要的理解了,其他的自己慢慢了解就行。
@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
//设置注入点,并获得前一个注入点,以便后面可以设置回来
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {//解析快捷方式,存在就返回,子类BeanFactiry可以扩展,默认null
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
Class<?> type = descriptor.getDependencyType();
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);//获取注解可能的值
if (value != null) {
if (value instanceof String) {
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ?
getMergedBeanDefinition(beanName) : null);
value = evaluateBeanDefinitionString(strVal, bd);
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
try {
return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
}
catch (UnsupportedOperationException ex) {
// A custom TypeConverter which does not support TypeDescriptor resolution...
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
}
//是否是多个bean的注入,比如参数类型是集合,map
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
//寻找装配候选对象
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
if (isRequired(descriptor)) {//空的话,又是必须的,才会报异常
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;//自动装配的bean名字
Object instanceCandidate;//装配实例
if (matchingBeans.size() > 1) {//有多个
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
}
else {
return null;
}
}
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
else {//只有一个
// We have exactly one match.
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
if (instanceCandidate instanceof Class) {//获取装配实例,也要进行getBean过程
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
Object result = instanceCandidate;
if (result instanceof NullBean) {
if (isRequired(descriptor)) {//不存在,又是必须
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
result = null;
}
if (!ClassUtils.isAssignableValue(type, result)) {//类型不匹配
throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
}
return result;
}
finally {//处理完后恢复当前注入点
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}
DefaultListableBeanFactory的findAutowireCandidates寻找自动装配类型
这里会去寻找我们的容器里面是否有参数的类型,先把参数类型的bean
定义中的所有bean
名字找出来,创建一个LinkedHashMap
集合,然后判断类型是不是内部的类型,是的话也要加进去。然后遍历候选名字集合,把非自引用的可以作为别人依赖的类型添加到集合中,如果集合为空,还要进行处理判断,比如是不是数组类型,集合类型,再做相应处理。
protected Map<String, Object> findAutowireCandidates(
@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
//获取requiredType对应的bean名字数组
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);
for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {//如果是依赖内部一些类的类型
Class<?> autowiringType = classObjectEntry.getKey();
if (autowiringType.isAssignableFrom(requiredType)) {
Object autowiringValue = classObjectEntry.getValue();
autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
if (requiredType.isInstance(autowiringValue)) {
result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
break;
}
}
}
for (String candidate : candidateNames) {//自定义的基本在这里
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);//非自引用,且可以为其他类做自动装配的,就加入集合
}
}
if (result.isEmpty()) {//空的处理
boolean multiple = indicatesMultipleBeans(requiredType);
// Consider fallback matches if the first pass failed to find anything...
DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
for (String candidate : candidateNames) {
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor) &&
(!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
if (result.isEmpty() && !multiple) {
// Consider self references as a final pass...
// but in the case of a dependency collection, not the very same bean itself.
for (String candidate : candidateNames) {
if (isSelfReference(beanName, candidate) &&
(!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&
isAutowireCandidate(candidate, fallbackDescriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
}
}
return result;
}
addCandidateEntry添加到候选集合里
如果是多元素集合和StreamDependencyDescriptor
类型的,会去创建相应的bean
,然后放入,否则就直接把类型放入进来。
private void addCandidateEntry(Map<String, Object> candidates, String candidateName,
DependencyDescriptor descriptor, Class<?> requiredType) {
if (descriptor instanceof MultiElementDescriptor) {
Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this);
if (!(beanInstance instanceof NullBean)) {
candidates.put(candidateName, beanInstance);
}
}
else if (containsSingleton(candidateName) || (descriptor instanceof StreamDependencyDescriptor &&
((StreamDependencyDescriptor) descriptor).isOrdered())) {
Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this);
candidates.put(candidateName, (beanInstance instanceof NullBean ? null : beanInstance));
}
else {
candidates.put(candidateName, getType(candidateName));
}
}
DependencyDescriptor的resolveCandidate
当我们解析出来要装配的类型的时候,就可以开始去真正的获取该类型的对象了,其实内部还是调用getBean
的。
public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)
throws BeansException {
return beanFactory.getBean(beanName);
}
大致的流程就分析到这里啦,很多细节还没深入,因为比较复杂,还是先把大致搞清楚在去琢磨细节比较好。下篇我们把基本的流程图总计下。
好了,今天就到这里了,希望对学习理解有帮助,大神看见勿喷,仅为自己的学习理解,能力有限,请多包涵。