Spring 5.x Source trip twenty-one Detailed seven getBean
DefaultListableBeanFactory of doResolveDependency resolve dependencies
Continue on articles, if it is our own definition of the type of parameters, there is no lazy loading notes, it will be resolved.
First look at BeanFactiry
whether there is to add a shortcut, generally do not, unless the subclass inherits extension, and then see if there are ways to set the parameter annotation value, any deal is set. Otherwise, it is judged whether a plurality bean
of injection, such as a set of parameter types. Finally, the object is to obtain automatic assembly type findAutowireCandidates
, if multiple find the words, priority will be to select, and then assembled to create the type of object here is to create a getBean
process, but it may be directly obtained, in general, it is defined in order to see the main factory method, since you can use the internal ASM
process, but if there are duplicate names, it is out of order, and you can see why not specific ConfigurationClassParser
of retrieveBeanMethodMetadata
method, but not much impact, anyway, can be automatically assembled. Creating good and then determine the type of match, and finally returned. Let's analyze several major ways, mainly to understand the other get to know yourself on the line.
@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);
}
}
Looking DefaultListableBeanFactory automatic assembly of the type findAutowireCandidates
Here we will look for whether there is inside a container type parameters, first parameter type of bean
all definitions of bean
name to find out, to create a LinkedHashMap
collection, and then determine the type is not the type of interior, that is the case should be added to the list. Then traverse the candidate set of names, the non-self-referencing others may be added as a dependent type to the collection, if the set is empty, but also determination processing, such is not array type, set type, do accordingly.
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 added to the candidate set in
If it is more than a collection of elements and StreamDependencyDescriptor
types will be appropriate to create bean
, and then into, or type directly into the room.
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
When we parse out the type of assembly time, you can start to really get that type of object, in fact, inside and call getBean
the.
public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)
throws BeansException {
return beanFactory.getBean(beanName);
}
General process to analyze it here, not a lot of details in depth, it is more complex, or the first figure out roughly in pondering the details better. Next we have the basic flow chart under total.
Well, here today, we hope to help study and understand, do not spray the Great God see, understand only their own learning, limited capacity, please excuse.