前面说到Spring 通过bytype注入,留下了一些没有诉说,现在来详细看看
protected void autowireByType(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
// 找到有对应set方法的属性
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
try {
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
// Don't try autowiring by type for type Object: never makes sense,
// even if it technically is a unsatisfied, non-simple property.
//这里是判断是你的属性描述器,也就是说你的set方法的参数的类型不能是Object
//因为如果setUserService(Object userService),那么像这个方法,如果是Object,spring根本不知道你要注入那个bean
//所以不能是Object
if (Object.class != pd.getPropertyType()) {
// set方法中的参数信息
//根据属性描述器获取这个set方法的参数信息
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
// Do not allow eager init for type matching in case of a prioritized post-processor.
boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);
/**
*
* 根据方法的参数MethodParameter获取一个bean
* 到这里知道这个方法是byType,byType的原理是根据你的set方法的参数类型得到一个bean,所以这里是通过
* set方法的参数比如setUserService(UserService uservice)中的UserService来构建一个依赖描述器
* 这个依赖描述器得到过后,根据这个依赖描述器和其他一些参数得到一个bean
*/
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
// 根据类型找bean,这就是byType
//简单来说就是根据依赖描述器通过下面这个方法得到一个Bean,然后注入到pvs中
//后面说
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {
pvs.add(propertyName, autowiredArgument);
}
for (String autowiredBeanName : autowiredBeanNames) {
registerDependentBean(autowiredBeanName, beanName);
if (logger.isTraceEnabled()) {
logger.trace("Autowiring by type from bean name '" + beanName + "' via property '" +
propertyName + "' to bean named '" + autowiredBeanName + "'");
}
}
autowiredBeanNames.clear();
}
} catch (BeansException ex) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
}
}
}
- 找到有对应set方法的属性
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
Set<String> result = new TreeSet<>();
PropertyValues pvs = mbd.getPropertyValues(); // 在BeanDefinition中添加的属性和值,
//
PropertyDescriptor[] pds = bw.getPropertyDescriptors();
// 对类里所有的属性进行过滤,确定哪些属性是需要进行自动装配的
for (PropertyDescriptor pd : pds) {
// 属性有set方法,并且
// 没有通过DependencyCheck排除,并且
// 没有在BeanDefinition中给该属性赋值,并且
// 属性的类型不是简单类型
if (pd.getWriteMethod() != null && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) &&
!BeanUtils.isSimpleProperty(pd.getPropertyType())) {
result.add(pd.getName());
}
}
// 返回过滤之后的结果,后续只对这些属性进行自动装配
return StringUtils.toStringArray(result);
}
- 得到属性描述
getPropertyDescriptor
,根据属性描述器获取这个set方法的参数信息getWriteMethodParameter
,然后根据方法的参数MethodParameter构建一个依赖描述器通过AutowireByTypeDependencyDescriptor
- 根据依赖描述器得到一个Bean通过
resolveDependency
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
// DependencyDescriptor表示一个依赖,可以是一个属性字段,可能是一个构造方法参数,可能是一个set方法参数
// 根据descriptor去BeanFactory中找到bean
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
// 如果依赖的类型是Optional
if (Optional.class == descriptor.getDependencyType()) {
return createOptionalDependency(descriptor, requestingBeanName);
}
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
}
else {
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
// 通过解析descriptor找到bean对象
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
- 判断descriptor.getDependencyType()的类型
- 若果依赖描述上存在@Lazy注解,那么会生成一个代理对象,然后返回包装成Optional否则调用doResolveDependen
通过解析依赖描述找到bean对象result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter)
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
// 如果DependencyDescriptor是一个ShortcutDependencyDescriptor,
// 那么会直接理解beanName从beanFactory中拿到一个bean,
// 在利用@Autowired注解来进行依赖注入时会利用ShortcutDependencyDescriptor来进行依赖注入的缓存,
// 表示当解析完某个依赖信息后,会把依赖的bean的beanName缓存起来
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
// 获取descriptor具体的类型,某个Filed的类型或某个方法参数的类型
Class<?> type = descriptor.getDependencyType();
// 获取@Value注解中所配置的值
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor); // 是否通过@Value注解指定了值
if (value != null) {
if (value instanceof String) {
// 先进行占位符的填充,解析"$"符号
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ?
getMergedBeanDefinition(beanName) : null);
// 解析Spring EL表达式,解析"#"符号(可以进行运算,可以写某个bean的名字)
value = evaluateBeanDefinitionString(strVal, bd);
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
try {
// 把value从descriptor.getTypeDescriptor()类型转化为type类
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()));
}
}
// 没有使用@Value注解
// 要注入的依赖的类型是不是一个Map、Array、Collection
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
// 通过type找,可能找到多个
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
// 根据type找到了多个
if (matchingBeans.size() > 1) {
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
}
else {
// In case of an optional Collection/Map, silently ignore a non-unique case:
// possibly it was meant to be an empty collection of multiple regular beans
// (before 4.3 in particular when we didn't even look for collection beans).
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) {
// 调用beanFactory.getBean(beanName);创建bean对象
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);
}
}
- 先判断是不是Shortcut,如果是那么可以理解beanName直接从beanFactory中拿到一个bean
// 如果DependencyDescriptor是一个ShortcutDependencyDescriptor,
// 那么会直接理解beanName从beanFactory中拿到一个bean,
// 在利用@Autowired注解来进行依赖注入时会利用ShortcutDependencyDescriptor来进行依赖注入的缓存,
// 表示当解析完某个依赖信息后,会把依赖的bean的beanName缓存起来
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
//------------------------------------------------------------------------------
@Override
public Object resolveShortcut(BeanFactory beanFactory) {
return beanFactory.getBean(this.shortcut, this.requiredType);
}
- 判断@Value注解是否存在,如果存在获取并解析descriptor上的@Value注解,并进行解析返回
// 获取@Value注解中所配置的值
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor); // 是否通过@Value注解指定了值
if (value != null) {
if (value instanceof String) {
// 先进行占位符的填充,解析"$"符号
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ?
getMergedBeanDefinition(beanName) : null);
// 解析Spring EL表达式,解析"#"符号(可以进行运算,可以写某个bean的名字)
value = evaluateBeanDefinitionString(strVal, bd);
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
try {
// 把value从descriptor.getTypeDescriptor()类型转化为type类
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()));
}
}
- 若果没有则判断descriptor的类型
- descriptor的类型为Collection,或者map则直接返回map的value或者map
// 没有使用@Value注解
// 要注入的依赖的类型是不是一个Map、Array、Collection
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
- 调用findAutowireCandidates(beanName, type, descriptor),该方法返回一个Map,表示会根据type去找bean,Map的key为beanName,Map的value为对象(注意可能是bena的对象,也可能是某个bean的class对象,因为该方法只负责根据类型找到对应的bean,如果该bean还没有实例化,那么该方法不负责去实例化,只返回该bean对应的Class对象,表示这个bean也是结果之一)
// 根据requiredType寻找自动匹配的候选者bean
protected Map<String, Object> findAutowireCandidates(
@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
// 根据requiredType找到candidateNames,表示根据type找到了候选beanNames
// Ancestors是祖先的意思,所以这个方法是去当前beanfactory以及祖先beanfactory中去找类型为requiredType的bean的名字
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);
// 先从resolvableDependencies
for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
Class<?> autowiringType = classObjectEntry.getKey();
// requiredType是autowiringType的子类
// 也就是,某个bean中的属性的类型是requiredType,是resolvableDependencies中的子类
if (autowiringType.isAssignableFrom(requiredType)) {
// 是resolvableDependencies中的子类所存的对象
Object autowiringValue = classObjectEntry.getValue();
autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
if (requiredType.isInstance(autowiringValue)) {
// 把resolvableDependencies中保存的对象作为当前属性的一个候选者
result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
break;
}
}
}
// 对候选bean进行过滤,首先候选者不是自己,然后候选者是支持自动注入给其他bean的
for (String candidate : candidateNames) {
// isAutowireCandidate方法中会去判断候选者是否和descriptor匹配
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;
}
- 判断根据type有没有找到bean
- 如果没有找到,判断是不是isRequired
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
- 如果找到判断是否超过一个,如果只有一个则则直接返回该bean,如果是Class对象,则调用getBean生成该bean对象
- 超过一个则调用determineAutowireCandidate(matchingBeans, descriptor)
// 根据type找到了多个
if (matchingBeans.size() > 1) {
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
}
else {
// In case of an optional Collection/Map, silently ignore a non-unique case:
// possibly it was meant to be an empty collection of multiple regular beans
// (before 4.3 in particular when we didn't even look for collection beans).
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();
}
在找到多个的情况下调用determineAutowireCandidate(matchingBeans, descriptor)
protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
Class<?> requiredType = descriptor.getDependencyType();
// 取@Primary的bean
String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
if (primaryCandidate != null) {
return primaryCandidate;
}
// 取优先级最高的bean
String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
if (priorityCandidate != null) {
return priorityCandidate;
}
// Fallback
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
String candidateName = entry.getKey();
Object beanInstance = entry.getValue();
if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||
// 根据属性名确定
matchesBeanName(candidateName, descriptor.getDependencyName())) {
return candidateName;
}
}
return null;
}
- 从多个Bean中选择被@Primary标注了的Bean,如果有多个@Primary会报错
String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
if (primaryCandidate != null) {
return primaryCandidate;
}
//---------------------------------------------------------------------
protected String determinePrimaryCandidate(Map<String, Object> candidates, Class<?> requiredType) {
String primaryBeanName = null;
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
String candidateBeanName = entry.getKey();
Object beanInstance = entry.getValue();
// 当前candidateBean是否@Primary
if (isPrimary(candidateBeanName, beanInstance)) {
if (primaryBeanName != null) {
boolean candidateLocal = containsBeanDefinition(candidateBeanName);
boolean primaryLocal = containsBeanDefinition(primaryBeanName);
if (candidateLocal && primaryLocal) {
throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(),
"more than one 'primary' bean found among candidates: " + candidates.keySet());
}
else if (candidateLocal) {
primaryBeanName = candidateBeanName;
}
}
else {
primaryBeanName = candidateBeanName;
}
}
}
return primaryBeanName;
}
- 如果没有@Primary,那么则看Bean上是否通过@Priority定义了优先级,如果定义了则获取优先级最高的Bean
// 取优先级最高的bean
String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
if (priorityCandidate != null) {
return priorityCandidate;
}
- 如果没有优先级,那么使用descriptor.getDependencyName()来确定一个唯一的Bean
- 判断是否找到唯一的Bean
- 找到后如果不是Class对象直接返回,如果是就通过getBean获取
- 如果没有找到,判断是否isRequired,如果是报错,不是就返回null
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
String candidateName = entry.getKey();
Object beanInstance = entry.getValue();
if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||
// 根据属性名确定
matchesBeanName(candidateName, descriptor.getDependencyName())) {
return candidateName;
}
}
- 整体流程