Spring源码-autowireByName

autowireByName

protected void autowireByName(
		String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

	String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
	for (String propertyName : propertyNames) {
		if (containsBean(propertyName)) {
			Object bean = getBean(propertyName);
			pvs.add(propertyName, bean);
			registerDependentBean(propertyName, beanName);
			if (logger.isTraceEnabled()) {
				logger.trace("Added autowiring by name from bean name '" + beanName +
						"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
			}
		}
		else {
			if (logger.isTraceEnabled()) {
				logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
						"' by name: no matching bean found");
			}
		}
	}
}
  1. 获取bw中有setter方法 且 非简单类型属性 且 mbd的PropertyValues中没有该pd的属性名的 PropertyDescriptor 属性名数组

  2. 遍历属性名数组,如果该bean工厂有propertyName的beanDefinition,则获取该bean并设置到pvs中,同时注册bean依赖

unsatisfiedNonSimpleProperties

protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
	Set<String> result = new TreeSet<>();
	PropertyValues pvs = mbd.getPropertyValues();
	PropertyDescriptor[] pds = bw.getPropertyDescriptors();
	for (PropertyDescriptor pd : pds) {
		if (pd.getWriteMethod() != null && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) &&
				!BeanUtils.isSimpleProperty(pd.getPropertyType())) {
			result.add(pd.getName());
		}
	}
	return StringUtils.toStringArray(result);
}

unsatisfiedNonSimpleProperties获取bw中有setter方法且非简单类型属性且mbd的PropertyValues中没有该pd的属性名的PropertyDescriptor属性名数组。

getWriteMethod

    public synchronized Method getWriteMethod() {
    Method writeMethod = this.writeMethodRef.get();
    if (writeMethod == null) {
        Class<?> cls = getClass0();
        if (cls == null || (writeMethodName == null && !this.writeMethodRef.isSet())) {
            // The write method was explicitly set to null.
            return null;
        }

        // We need the type to fetch the correct method.
        Class<?> type = getPropertyType0();
        if (type == null) {
            try {
                // Can't use getPropertyType since it will lead to recursive loop.
                type = findPropertyType(getReadMethod(), null);
                setPropertyType(type);
            } catch (IntrospectionException ex) {
                // Without the correct property type we can't be guaranteed
                // to find the correct method.
                return null;
            }
        }

        if (writeMethodName == null) {
            writeMethodName = Introspector.SET_PREFIX + getBaseName(); //     static final String SET_PREFIX = "set";
        }

        Class<?>[] args = (type == null) ? null : new Class<?>[] { type };
        writeMethod = Introspector.findMethod(cls, writeMethodName, 1, args);
        if (writeMethod != null) {
            if (!writeMethod.getReturnType().equals(void.class)) {
                writeMethod = null;
            }
        }
        try {
            setWriteMethod(writeMethod);
        } catch (IntrospectionException ex) {
            // fall through
        }
    }
    return writeMethod;
}

getWriteMethod获取set方法。

isExcludedFromDependencyCheck:

protected boolean isExcludedFromDependencyCheck(PropertyDescriptor pd) {
	return (AutowireUtils.isExcludedFromDependencyCheck(pd) ||
			this.ignoredDependencyTypes.contains(pd.getPropertyType()) ||     // ignoredDependencyTypes保存了忽略依赖检查的类型
			AutowireUtils.isSetterDefinedInInterface(pd, this.ignoredDependencyInterfaces)); // ignoredDependencyInterfaces保存了忽略依赖检查的接口
}

isExcludedFromDependencyCheck判断pd的属性是CGLIB定义的属性 或者 该工厂的忽略依赖类型列表中包含该pd的属性类型 或者 pd的属性是ignoredDependencyInterfaces里面的接口定义的方法。

isExcludedFromDependencyCheck:

public static boolean isExcludedFromDependencyCheck(PropertyDescriptor pd) {
	Method wm = pd.getWriteMethod();
	if (wm == null) {
		return false;
	}
	if (!wm.getDeclaringClass().getName().contains("$$")) {
		// Not a CGLIB method so it's OK.
		return false;
	}
	// It was declared by CGLIB, but we might still want to autowire it
	// if it was actually declared by the superclass.
	Class<?> superclass = wm.getDeclaringClass().getSuperclass();
	return !ClassUtils.hasMethod(superclass, wm);
}

isExcludedFromDependencyCheck判断是否是cglib代理对象,若不是返回false,若是判断cglib代理的对象是否存在set方法。

isSetterDefinedInInterface:

public static boolean isSetterDefinedInInterface(PropertyDescriptor pd, Set<Class<?>> interfaces) {
	Method setter = pd.getWriteMethod();
	if (setter != null) {
		Class<?> targetClass = setter.getDeclaringClass();
		for (Class<?> ifc : interfaces) {
			if (ifc.isAssignableFrom(targetClass) && ClassUtils.hasMethod(ifc, setter)) {
				return true;
			}
		}
	}
	return false;
}

isSetterDefinedInInterface方法判断set方法是否在接口中定义且有此方法。

isSimpleProperty:

public static boolean isSimpleProperty(Class<?> type) {
	Assert.notNull(type, "'type' must not be null");
	return isSimpleValueType(type) || (type.isArray() && isSimpleValueType(type.getComponentType()));
}

isSimpleProperty判断是否是简单值或者是简单值的数组。

isSimpleValueType

public static boolean isSimpleValueType(Class<?> type) {
	return (Void.class != type && void.class != type &&
			(ClassUtils.isPrimitiveOrWrapper(type) ||  // isPrimitiveOrWrapper判断是否是基本类型及其包装类
			Enum.class.isAssignableFrom(type) ||
			CharSequence.class.isAssignableFrom(type) ||
			Number.class.isAssignableFrom(type) ||
			Date.class.isAssignableFrom(type) ||
			Temporal.class.isAssignableFrom(type) ||
			URI.class == type ||
			URL.class == type ||
			Locale.class == type ||
			Class.class == type));
}

containsBean

	@Override
public boolean containsBean(String name) {
	String beanName = transformedBeanName(name);
	if (containsSingleton(beanName) || containsBeanDefinition(beanName)) {
		return (!BeanFactoryUtils.isFactoryDereference(name) || isFactoryBean(name));
	}
	// Not found -> check parent.
	BeanFactory parentBeanFactory = getParentBeanFactory();
	return (parentBeanFactory != null && parentBeanFactory.containsBean(originalBeanName(name)));
}

containsBean判断bean工厂有propertyName的beanDefinition或bean是否在singletonObjects中。

posted @ 2022-10-01 11:52  shigp1  阅读(68)  评论(0编辑  收藏  举报