org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
属性注入注解方式和xml配置方式,使用不同的逻辑。
注解通过从beanFactory中找实例,反射注入;xml则是通过PropertyValues,反射调用set方法注入。
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
。。。。。
// bean处理器的方法,实例化后处理方法
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}
// 这里得到的是xml配置中设置的属性-值
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
// 如果设置为自动注入。
// AUTOWIRE_BY_NAME会根据属性的名称,从beanFactory中找bean,添加到newPvs属性集合中
// AUTOWIRE_BY_TYPE根据属性的类型找bean,添加到属性集合中
// 当然如果已经在xml中设置值的就不会在找了
// xml是手动设置,这里是自动配置,直接根据属性的名称或者类型找bean.
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
// 这里是注解注入的处理逻辑,使用bean处理器的方法。
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
// 这里设值是属性集合中的属性键值对。
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
xml配置的bean,会将属性和值封装在PropertyValue中,添加到属性集合中,通过反射调用set方法注入。逻辑在applyPropertyValues方法中;
注解的注入则是使用bean处理器,通过反射直接对属性赋值。
直接分析注解的方式,先来看看注解的使用:
@Autowired注解:可以标注在属性上,方法上。
- 标注在属性上,会根据属性的类型找bean。标注在方法上,会根据方法参数的类型找bean.如果有多个类型一致的;会跑异常,解决方式设置@primary bean,设置一个候选的。或者在类型一致的里面根据名称选出一个bean,使用@Qualifier注解;
@Resource注解:可以标注在属性上,方法上,但是这个方法的参数个数必须是1个。
- 标注在属性上,默认是@Resource的value值作为找bean的名称;如果没有,使用属性的名称;如果不存在该名称的bean,会根据bean的类型找;如果标注在方法上,如果这个方法的名称不是JavaBean规范,那么会根据方法名成找bean,没有找到会根据方法参数的类型找。如果是javaBean规范,那么找bean的名称就是属性名称,根据名称找,根据bean名称没有找到,会根据参数类型找。
使用@Resource注入,需要明确是@Resource不是Spring的注解,是JSR标准
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#postProcessProperties直接看这个注入的方法了,其实在依赖输入之前,postProcessMergedBeanDefinition这个方法会进行依赖注入的解析,保存缓存中,在postProcessProperties是从缓存找取,执行注入逻辑。所以直接看postProcessProperties方法也无妨。
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
// 缓存了需要输入数据的信息
Injectionmetadata metadata = findResourcemetadata(beanName, bean.getClass(), pvs);
try {
// 注入逻辑。
metadata.inject(bean, beanName, pvs);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);
}
return pvs;
}
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#buildResourcemetadata
解析需要注入的信息
private Injectionmetadata buildResourcemetadata(final Class> clazz) {
if (!AnnotationUtils.isCandidateClass(clazz, resourceAnnotationTypes)) {
return Injectionmetadata.EMPTY;
}
List elements = new ArrayList<>();
Class> targetClass = clazz;
do {
final List currElements = new ArrayList<>();
// 得到所有的属性信息
ReflectionUtils.doWithLocalFields(targetClass, field -> {
// 兼容其他注解
。。。。。。
// 我们只关注Resource注解的。
else if (field.isAnnotationPresent(Resource.class)) {
// 静态的属性不能注入
if (Modifier.isStatic(field.getModifiers())) {
throw new IllegalStateException("@Resource annotation is not supported on static fields");
}
// 将属性封装为ResourceElement
if (!this.ignoredResourceTypes.contains(field.getType().getName())) {
currElements.add(new ResourceElement(field, field, null));
}
}
});
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
if (method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
// 兼容其他注解
。。。。。
// 只看Resource注解
else if (bridgedMethod.isAnnotationPresent(Resource.class)) {
// 静态的方法不能注入
if (Modifier.isStatic(method.getModifiers())) {
throw new IllegalStateException("@Resource annotation is not supported on static methods");
}
// 方法参数个数不是1的会抛异常。
Class>[] paramTypes = method.getParameterTypes();
if (paramTypes.length != 1) {
throw new IllegalStateException("@Resource annotation requires a single-arg method: " + method);
}
// 封装为ResourceElement
if (!this.ignoredResourceTypes.contains(paramTypes[0].getName())) {
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new ResourceElement(method, bridgedMethod, pd));
}
}
}
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}
// 循环,从父类中是否有标注注解的。
while (targetClass != null && targetClass != Object.class);
return Injectionmetadata.forElements(elements, clazz);
}
解析注解:
- 静态属性和静态方法不能出入;方法的参数个数必须是1个,否则会跑异常。将数据给封装在ResourceElement再添加到集合中。
注入逻辑:
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Collection checkedElements = this.checkedElements;
Collection elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
// 遍历InjectedElement集合,调用InjectedElement 的注入方法。
for (InjectedElement element : elementsToIterate) {
if (logger.isTraceEnabled()) {
logger.trace("Processing injected element of bean '" + beanName + "': " + element);
}
element.inject(target, beanName, pvs);
}
}
}
protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs)
throws Throwable {
// 属性,通过反射
if (this.isField) {
Field field = (Field) this.member;
ReflectionUtils.makeAccessible(field);
field.set(target, getResourceToInject(target, requestingBeanName));
}
else {
if (checkPropertySkipping(pvs)) {
return;
}
try {
// 方法,方法的反射。
Method method = (Method) this.member;
ReflectionUtils.makeAccessible(method);
method.invoke(target, getResourceToInject(target, requestingBeanName));
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
getResourceToInject通过该方法得到值;
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.ResourceElement#getResourceToInject
protected Object getResourceToInject(Object target, @Nullable String requestingBeanName) {
//这里有一个懒加载的操作。
// 如果使用@lazy注解标注了,会给创建一个代理,只有再使用的时候才会取bean工厂中找bean
//非懒加载的会立刻执行找bean的逻辑,返回结果。懒加载是先返回要给代理,等调用放的时候再去执行找bean的过程。
return (this.lazyLookup ? buildLazyResourceProxy(this, requestingBeanName) :
getResource(this, requestingBeanName));
}
protected Object autowireResource(BeanFactory factory, LookupElement element, @Nullable String requestingBeanName)
throws NoSuchBeanDefinitionException {
Object resource;
Set autowiredBeanNames;
// 如果是属性,这里是注解value的值,没有指定,就是属性的名称
// 如果是方法,javabean标准,是属性名称;不是javaBean标准,则是方法名称。
String name = element.name;
if (factory instanceof AutowireCapableBeanFactory) {
AutowireCapableBeanFactory beanFactory = (AutowireCapableBeanFactory) factory;
DependencyDescriptor descriptor = element.getDependencyDescriptor();
// 如果按照名称找,但是名称没有,就按类型找。
if (this.fallbackToDefaultTypeMatch && element.isDefaultName && !factory.containsBean(name)) {
autowiredBeanNames = new linkedHashSet<>();
resource = beanFactory.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, null);
if (resource == null) {
throw new NoSuchBeanDefinitionException(element.getLookupType(), "No resolvable resource object");
}
}
// 按照名称找。
else {
resource = beanFactory.resolveBeanByName(name, descriptor);
autowiredBeanNames = Collections.singleton(name);
}
}
else {
resource = factory.getBean(name, element.lookupType);
autowiredBeanNames = Collections.singleton(name);
}
if (factory instanceof ConfigurableBeanFactory) {
ConfigurableBeanFactory beanFactory = (ConfigurableBeanFactory) factory;
for (String autowiredBeanName : autowiredBeanNames) {
if (requestingBeanName != null && beanFactory.containsBean(autowiredBeanName)) {
beanFactory.registerDependentBean(autowiredBeanName, requestingBeanName);
}
}
}
return resource;
}
按照名称找不到,就会按照类型找。
public ResourceElement(Member member, AnnotatedElement ae, @Nullable PropertyDescriptor pd) {
super(member, pd);
Resource resource = ae.getAnnotation(Resource.class);
// Resource 指定的bean名称
String resourceName = resource.name();
Class> resourceType = resource.type();
this.isDefaultName = !StringUtils.hasLength(resourceName);
// 如果使用默认的名称
if (this.isDefaultName) {
// 属性名称或者方法名称
resourceName = this.member.getName();
// 如果是方法,兵器是set开头,长度>3,是javaBean规范
// 内省机制找到属性名。否则还是方法名称。
if (this.member instanceof Method && resourceName.startsWith("set") && resourceName.length() > 3) {
resourceName = Introspector.decapitalize(resourceName.substring(3));
}
}
else if (embeddedValueResolver != null) {
resourceName = embeddedValueResolver.resolveStringValue(resourceName);
}
if (Object.class != resourceType) {
checkResourceType(resourceType);
}
else {
// No resource type specified... check field/method.
resourceType = getResourceType();
}
this.name = (resourceName != null ? resourceName : "");
this.lookupType = resourceType;
String lookupValue = resource.lookup();
this.mappedName = (StringUtils.hasLength(lookupValue) ? lookupValue : resource.mappedName());
Lazy lazy = ae.getAnnotation(Lazy.class);
this.lazyLookup = (lazy != null && lazy.value());
}
AutowiredAnnotationBeanPostProcessor
使用@Autowired注解注入。该注解是Spring的注解。
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#buildResourcemetadata
private Injectionmetadata buildAutowiringmetadata(final Class> clazz) {
if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
return Injectionmetadata.EMPTY;
}
List elements = new ArrayList<>();
Class> targetClass = clazz;
do {
final List currElements = new ArrayList<>();
// 遍历所有的属性
ReflectionUtils.doWithLocalFields(targetClass, field -> {
// 属性使用注解标准@Autowired,@Value,@Inject
// @Inject是JSR标注的注解。
MergedAnnotation> ann = findAutowiredAnnotation(field);
if (ann != null) {
// 静态的不行
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static fields: " + field);
}
return;
}
// 封装为AutowiredFieldElement
boolean required = determineRequiredStatus(ann);
currElements.add(new AutowiredFieldElement(field, required));
}
});
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
MergedAnnotation> ann = findAutowiredAnnotation(bridgedMethod);
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
// 静态的不行
if (Modifier.isStatic(method.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static methods: " + method);
}
return;
}
if (method.getParameterCount() == 0) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation should only be used on methods with parameters: " +
method);
}
}
// 封装为AutowiredMethodElement
boolean required = determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new AutowiredMethodElement(method, required, pd));
}
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
return Injectionmetadata.forElements(elements, clazz);
}
- 静态的都不行属性封装为AutowiredFieldElement;方法封装为AutowiredMethodElement
属性:
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
if (this.cached) {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
else {
// 得到属性的类型
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set autowiredBeanNames = new linkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
//根据类型找
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
synchronized (this) {
// 放入缓存
if (!this.cached) {
if (value != null || this.required) {
this.cachedFieldValue = desc;
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
this.cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
else {
this.cachedFieldValue = null;
}
this.cached = true;
}
}
}
// 反射给属性赋值
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
}
方法:
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
if (checkPropertySkipping(pvs)) {
return;
}
Method method = (Method) this.member;
Object[] arguments;
if (this.cached) {
// Shortcut for avoiding synchronization...
arguments = resolveCachedArguments(beanName);
}
else {
int argumentCount = method.getParameterCount();
arguments = new Object[argumentCount];
DependencyDescriptor[] descriptors = new DependencyDescriptor[argumentCount];
Set autowiredBeans = new linkedHashSet<>(argumentCount);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
// 遍历每一个方法参数
for (int i = 0; i < arguments.length; i++) {
MethodParameter methodParam = new MethodParameter(method, i);
// 得到该参数的类型
DependencyDescriptor currDesc = new DependencyDescriptor(methodParam, this.required);
currDesc.setContainingClass(bean.getClass());
descriptors[i] = currDesc;
try {
//根据类型找
Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter);
if (arg == null && !this.required) {
arguments = null;
break;
}
//找到的bean放再数组中
arguments[i] = arg;
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(methodParam), ex);
}
}
synchronized (this) {
if (!this.cached) {
if (arguments != null) {
DependencyDescriptor[] cachedMethodArguments = Arrays.copyOf(descriptors, arguments.length);
registerDependentBeans(beanName, autowiredBeans);
if (autowiredBeans.size() == argumentCount) {
Iterator it = autowiredBeans.iterator();
Class>[] paramTypes = method.getParameterTypes();
for (int i = 0; i < paramTypes.length; i++) {
String autowiredBeanName = it.next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) {
cachedMethodArguments[i] = new ShortcutDependencyDescriptor(
descriptors[i], autowiredBeanName, paramTypes[i]);
}
}
}
this.cachedMethodArguments = cachedMethodArguments;
}
else {
this.cachedMethodArguments = null;
}
this.cached = true;
}
}
}
// 反射,执行该方法。
if (arguments != null) {
try {
ReflectionUtils.makeAccessible(method);
method.invoke(bean, arguments);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
有个问题;静态的属性和方法都还不能用注解,那如果就是想用静态的怎么版呢?
解决静态属性,静态方法注入的问题可以这样
@Component
public class UserHelper {
static UCClient ucClient;
@Autowired
public void setUcClient(UCClient ucClient) {
UserHelper.ucClient = ucClient;
}
}
但是想想工具类都是静态的,不用交给spring管理。
SmartInitializingSingleton该接口会在所有的bean都实例化之后调用
@Component
public class AutowireStaticSmartInitializingSingleton implements SmartInitializingSingleton {
@Autowired
private AutowireCapableBeanFactory beanFactory;
@Override
public void afterSingletonsInstantiated() {
// 交给工厂,给我注如,
beanFactory.autowireBean(new UserHelper());
}
}
这样该类就不用加@Component注解。工具类交给beanFactory,让工厂注入。
public class UserHelper {
static UCClient ucClient;
@Autowired
public void setUcClient(UCClient ucClient) {
UserHelper.ucClient = ucClient;
}
}
或者这样:
@Component
public class AutowireStaticSmartInitializingSingleton implements SmartInitializingSingleton {
@Autowired
private AutowiredAnnotationBeanPostProcessor autowiredAnnotationBeanPostProcessor;
// 就是让处理器给注入
@Override
public void afterSingletonsInstantiated() {
autowiredAnnotationBeanPostProcessor.processInjection(new UserHelper());
}
}
还有一个问题,就是工厂找bean,是如何找的呢?就是方法beanFactory.resolveDependency的逻辑是什么样呢?
beanFactory.resolveDependency方法public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName, @Nullable SetautowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor); try { Object shortcut = descriptor.resolveShortcut(this); if (shortcut != null) { return shortcut; } Class> type = descriptor.getDependencyType(); // 解析@value注解的value值 // @value(#{beanName}) 注入的是bean // @value(${property-key}) 属性赋值 // value 不用的表达式,结果式不同的 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())); } } // 如果类型是集合类型的,数组,集合,Map,进入到此 Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter); if (multipleBeans != null) { return multipleBeans; } // 不是集合类型的,就直接找对应的类型。 Map matchingBeans = findAutowireCandidates(beanName, type, descriptor); if (matchingBeans.isEmpty()) { // 如果没有找到,还是必须的,那么就抛异常 if (isRequired(descriptor)) { raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor); } return null; } String autowiredBeanName; Object instanceCandidate; // 如果找到了,有多个候选的 if (matchingBeans.size() > 1) { // 筛选 // 1. 设置primary // 2. Priority注解 // 3.bean的名称和属性的名称匹配。 // 如果还欸有筛选出来就抛异常 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 entry = matchingBeans.entrySet().iterator().next(); autowiredBeanName = entry.getKey(); instanceCandidate = entry.getValue(); } if (autowiredBeanNames != null) { autowiredBeanNames.add(autowiredBeanName); } if (instanceCandidate instanceof Class) { 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); } }
- 处理@value注解类型是集合类型的普通类类型的。如果没有找到,又是必须的,报错如果找到了多个,就筛选1,设置primary的,2.注解Priority的,3.bean名和属性名一致的;如果还灭有筛选出来就报错。
找出对应类型的所有bean
protected MapfindAutowireCandidates( @Nullable String beanName, Class> requiredType, DependencyDescriptor descriptor) { //遍历所有的beanName,从里面找出beanDefinition,找出class,对比clas类型和requiredType String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this, requiredType, true, descriptor.isEager()); Map result = new linkedHashMap<>(candidateNames.length); // 处理spring内部的实例 // applicationcontext ,beanFactory等。。 for (Map.Entry , 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; } } } // 得到所有类型一样的 // 进行泛型和@Qualifier的筛选 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; }
- 找到所有的类型一样的泛型筛选@Qualifier筛选名称。
泛型是精确匹配:
注入的是RedisTemplate



