java-spring 09 上.populateBean 方法 (自动装配 --autowire属性,byname,bytype),resolveDependency方法

1.populateBean方法:
populateBean()方法位于的AbstractAutowireCapableBeanFactory类中,作用是将属性值填充到Bean对象中。 即属性注入阶段的实现方法。spring通过该方法,实现属性注入,在bean的实例化阶段,完成属性注入操作。

	// AbstractAutowireCapableBeanFactory#populateBean
	// beanName : bean 的name
	// mbd  :  bean的定义信息
	// bw  : bean实例的包装类型,里面有bean的实例
	protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {	
		if (bw == null) {
			// 没有属性抛出异常
			if (mbd.hasPropertyValues()) {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
			}
			else {
				// Skip property population phase for null instance.
				// 跳过属性填充阶段以获取空实例
				return;
			}
		}
		// 1. 属性填充判断 : 这里调用了 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation方法
		// 给InstantiationAwareBeanPostProcessor最后一次机会在属性设置前来改变bean
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;						
					// 返回值为是否继续填充bean
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						return;
					}
				}
			}
		}

		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

		int resolvedAutowireMode = mbd.getResolvedAutowireMode();
		// 2. 自动装配 :根据名称或类型自动注入
		if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
			// Add property values based on autowire by name if applicable.
			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();
			}
			// 3. 成员变量的注入
			// 调用了InstantiationAwareBeanPostProcessor.postProcessProperties 方法 和 postProcessPropertyValues 方法 来进行设值后处理
			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);
						}
						// 如果postProcessProperties 返回null,再调用 postProcessPropertyValues这个过时的方法
						pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						if (pvsToUse == null) {
							return;
						}
					}
					pvs = pvsToUse;
				}
			}
		}
		// 如果需要检查
		if (needsDepCheck) {
			if (filteredPds == null) {
				filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
			}
			// 依赖检查,对应 depends-on 属性,3.0 已弃用
			checkDependencies(beanName, mbd, filteredPds, pvs);
		}

		if (pvs != null) {
			// 4. 将属性应用到bean中
			applyPropertyValues(beanName, mbd, bw, pvs);
		}
	}



  1. populateBean 方法这一段代码 执行实例化后
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;						
					// 返回值为是否继续填充bean postProcessAfterInstantiation 实例化bean之后,相当于new这个bean之后,属性注入前触发执行
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						return;
					}
				}
			}
		}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

2.1 hasInstantiationAwareBeanPostProcessors 方法:判断集合是不是为空

	protected boolean hasInstantiationAwareBeanPostProcessors() {
		return !getBeanPostProcessorCache().instantiationAware.isEmpty();
	}

2.2 getBeanPostProcessors方法

InstantiationAwareBeanPostProcessor接口扩展了BeanPostProcessor子接口,提供了Bean被实例化之前、Bean实例化之后、Bean属性装配前更细粒度控制Bean创建流程的处理。

	public List<BeanPostProcessor> getBeanPostProcessors() {
		return this.beanPostProcessors;
	}

2.3 postProcessAfterInstantiation方法
这个是实例化后的方法

@Component
public class UserService   implements InstantiationAwareBeanPostProcessor {
	@Override
	public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        //这个是实例化后的操作
		return true;
	}	
}

3.populateBean 方法这一段

		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

		int resolvedAutowireMode = mbd.getResolvedAutowireMode();

3.1 mbd.hasPropertyValues方法

default boolean hasPropertyValues() {
		return !getPropertyValues().isEmpty();
	}

3.2 mbd.getPropertyValues方法

	@Nullable
	private MutablePropertyValues propertyValues;

	public MutablePropertyValues getPropertyValues() {
		if (this.propertyValues == null) {
			this.propertyValues = new MutablePropertyValues();
		}
		return this.propertyValues;
	}

3.2.1 MutablePropertyValues数据类型:

id:Bean 唯一标识名称。
beanClass:类全限定名(包名+类名)。
init-method:定义 Bean 初始化方法,Bean 组装之后调用,必须是一个无参数方法。
destory-method:定义 Bean 销毁方法,在 BeanFactory 关闭时触发,同样也必须是一个无参构造方法,只能应用于 SingletonBean 单例 Bean。
factory-method:定义创建 Bean 对象的工厂方法,用于下面的 factory-bean,表示这个 Bean 是通过工厂方法创建,此时,class 属性 “失效”。
factory-bean:定义创建该 Bean 的工厂类,如果使用了 factory-bean,则 class 属性相当于 “失效”。
MultablePropertyValues:用于封装类属性的集合,里面是一个 List 容器,包装了很多 PropertyValue ,一个 PropertyValue 封装了一个属性及其对应的值,可以说一个属性及其值就是一个 PropertyValue,当我们需要再 BeanDefinition 中修改某个类里面的属性时就可以使用该类。
ConstructorArgumentValues:用来在 BeanDefinition 模版中指定使用哪个构造方法进行实例化 Bean,这个参数在集成 MyBatis 框架就使用到了。

那么这个类有什么作用呢?

目前据我了解到的这个类可以帮助我们在 BeanDefinition 中修改某个类的属性

举例:

public class ProcessorEntity {

    private String name = "ABC";
    
    private Integer birthday;

	@Autowired
	public ProcessorEntity(Integer birthday) {
		System.out.println("birthdaybirthdaybirthdaybirthday");
	}

	public ProcessorEntity(String name) {
		System.out.println("namenamenamenamenam");
	}

	
	public Integer getBirth() {
		return birthday;
	}

	public void setBirth(Integer birthday) {
		this.birthday = birthday;
	}

	public String getName() {
		System.out.println("getName() 方法中的 scannerEntity = " + scannerEntity);
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}

ProcessorEntity 类我们通过 BeanDefinitionRegistryPostProcessor 手动注册,这样也可以比较方便的对 BeanDefinition 进行修改。

定义一个 MyConfigurationPostProcessor1 类获取到 BeanDefinition 定义,可以借助 BeanDefinitionRegistryPostProcessor 接口,如下:


@Component
public class MyConfigurationPostProcessor1 implements BeanDefinitionRegistryPostProcessor {
	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
	}

	@Override
	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
		GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition();
		genericBeanDefinition.setBeanClass(ProcessorEntity.class);
		MutablePropertyValues propertyValues = genericBeanDefinition.getPropertyValues();
		// 修改 ProcessorEntity 类中 name 属性默认值
		propertyValues.addPropertyValue("name","小明");
		
		// 然后再将 BeanDefinition 注册到 BeanFactory 容器中
		registry.registerBeanDefinition("processorEntity",genericBeanDefinition);
	}
}

容器拿到之后,假设现在要对 ProcessorEntity 类的属性 name 赋值,或者说是修改,应该怎么做呢?

可以将属性 name 和要设置的值封装成 PropertyValue,然后添加到 MutablePropertyValues 容器中即可,这样 Spring 自动帮咱们实现属性的设置。

其中代码 propertyValues.addPropertyValue(“name”,“小明”) 就是将 name=小明 封装到 PropertyValue,并添加到 MutablePropertyValues 容器,可以从源码看出,如下:

在这里插入图片描述

3.2.2
getPropertyValues方法的应用:在修改beandefinition上,自定义属性赋值

举例:
在MergedBeanDefinitionPostProcessor接口
在这里插入图片描述
3.3 getResolvedAutowireMode方法:
用到的常量:

	public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;
	int AUTOWIRE_BY_TYPE = 2;
	public static final int AUTOWIRE_CONSTRUCTOR = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR;
	int AUTOWIRE_CONSTRUCTOR = 3;
	public static final int AUTOWIRE_AUTODETECT = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT;
	int AUTOWIRE_AUTODETECT = 4;

getResolvedAutowireMode方法:

	public int getResolvedAutowireMode() {
		if (this.autowireMode == AUTOWIRE_AUTODETECT) {
		
			Constructor<?>[] constructors = getBeanClass().getConstructors();//获取当前bean的所有的构造函数
			for (Constructor<?> constructor : constructors) {
				if (constructor.getParameterCount() == 0) {//如果是无参构造
					return AUTOWIRE_BY_TYPE;
				}
			}
			return AUTOWIRE_CONSTRUCTOR;
		}
		else {
			return this.autowireMode;
		}
	}
  1. populateBean 方法这一段(很少用到了)
	if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
			// Add property values based on autowire by name if applicable.
			if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
				// 根据 beanName 进行装配
				autowireByName(beanName, mbd, bw, newPvs);
			}
			// Add property values based on autowire by type if applicable.
			if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
				// 根据 bean 类型进行装配
				autowireByType(beanName, mbd, bw, newPvs);
			}
			pvs = newPvs;
		}

在下面这段代码中,对 AUTOWIRE_BY_NAME 类型和 AUTOWIRE_BY_TYPE 的 种类进行自动装配。

public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;
public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;
AutowireCapableBeanFactory.AUTOWIRE_BY_NAME = 1;
AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE = 2;

这一段代码的目的是,如果bean在声明的时候指定了自动注入类型是 byName或者byType,则会根据这个规则,对 bean内部的排除某些特定的属性(排除规则后面详解), 进行byName 或者 byType的自动装配。


4.1什么是指定了自动注入类型是 byName或者byType或者no,default,constructor(getResolvedAutowireMode方法用到了后三个)
举例:这里一般是用在@bean注解中或者xml的<bean>用到的属性autowired

4.1.1 autowired=byName 这代表使用autowired的bean的相关属性自动注入依靠name

4.1.1.1 在配置文件中如何用autowired?

在xml文件中的bean标签中用属性autowire来写

<bean id="userService" class="com.zhouyu.UserService" autowire="byName"/>

或者在配置类文件中,在@Bean(autowire = Autowire.BY_NAME)

@ComponentScan

public class AppConfig {
	@Bean(autowire = Autowire.BY_NAME)
	public UserService UserService() {
		return new UserService();
	}
}

4.1.1.2 bean对应的类的具体代码:这里例子中重点是setOrderService这个方法

@Component

public class UserService    {

	private  OrderService orderService;

	public void setOrderService(OrderService orderService) {
		this.orderService = orderService;
	}
	
	public void test(){
		System.out.println("123");
	}
}

以setOrderService为例,spring容器会按照setOrderService名称的首字母小写orderService去容器中查找同名的bean对象,找到后会通过该set方法进行属性注入。

4.1.1.3具体的运用

实例类:

public class TestService {

    public TestService() {
        System.out.println("TestService初始化了");
    }
}

public class TestController {

    private TestService testService;

    public TestController() {
        System.out.println("testController初始化了");
    }
	
	// 这里注意他是按照set方法的参数名称去容器当中找这个对象的
    public void setTestService(TestService testService) {
        System.out.println("testService的set方法执行了");
        this.testService = testService;
    }

    @Override
    public String toString() {
        return "TestController{" +
                "testService=" + testService +
                '}';
    }
}

xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <bean id="testService" class="com.gzl.cn.service.TestService"/>
    <bean id="testController" class="com.gzl.cn.controller.TestController" autowire="byName"/>
</beans>

spring容器启动:

import com.gzl.cn.controller.TestController;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Client {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("classpath:bean.xml");
        TestController testController = (TestController)classPathXmlApplicationContext.getBean("testController");
        System.out.println(testController);
    }
}

运行效果:
在这里插入图片描述
4.1.2 autowired=byType 这代表使用autowired的bean的相关属性自动注入依靠Type

4.1.2.1使用 autowired=byType
在xml文件中:

<bean id="" class="X类" autowire="byType"/>

或者在配置类中

@ComponentScan

public class AppConfig {
	@Bean(autowire = Autowire.BY_TYPE)
	public UserService UserService() {
		return new UserService();
	}
}

4.1.2.2 具体过程 在所有set方法中找参数类型相同(参数数量只有一个)的那个方法执行

spring容器会遍历x类中所有的set方法,会在容器中查找和set参数类型相同的bean对象,将其通过set方法进行注入,未找到对应类型的bean对象则set方法不进行注入。需要注入的set属性的类型和被注入的bean的类型需要满足isAssignableFrom关系。按照类型自动装配的时候,如果按照类型找到了多个符合条件的bean,系统会报错。

在这里插入图片描述
4.1.2.3 案例:

<bean id="testService" class="com.gzl.cn.service.TestService"/>
<bean id="testController" class="com.gzl.cn.controller.TestController" autowire="byType"></bean>

运行结果:
在这里插入图片描述

4.1.3 autowired=constructor

4.1.3.1使用 autowired=constructor

<bean id="" class="X类" autowire="constructor"/>

在配置类中已经在 @Bean不用这个autowire = Autowire.CONSTRUCTOR

4.1.3.2 具体过程

spring会找到x类中所有的构造方法(一个类可能有多个构造方法),然后将这些构造方法进行排序(先按修饰符进行排序,public的在前面,其他的在后面,如果修饰符一样的,会按照构造函数参数数量倒叙,也就是采用贪婪的模式进行匹配,spring容器会尽量多注入一些需要的对象)得到一个构造函数列表,会轮询这个构造器列表,判断当前构造器所有参数是否在容器中都可以找到匹配的bean对象,如果可以找到就使用这个构造器进行注入,如果不能找到,那么就会跳过这个构造器,继续采用同样的方式匹配下一个构造器,直到找到一个合适的为止。

4.1.3.3 代码
xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="service1" class="com.gzl.cn.bean.DiAutowireByConstructor.Service1">
        <property name="desc" value="service1"/>
    </bean>
    <bean id="service2" class="com.gzl.cn.bean.DiAutowireByConstructor.Service2">
        <property name="desc" value="service2"/>
    </bean>

    <bean id="diAutowireByConstructor" class="com.gzl.cn.bean.DiAutowireByConstructor" autowire="constructor"/>
</beans>

public class DiAutowireByConstructor {

    public static class BaseServie {
        private String desc;

        public void setDesc(String desc) {
            this.desc = desc;
        }

        @Override
        public String toString() {
            return "BaseServie{" +
                    "desc='" + desc + '\'' +
                    '}';
        }
    }

    // Service1实现了IService1接口,还继承了BaseServie
    public static class Service1 extends BaseServie {

    }

    // Service1实现了IService1接口,还继承了BaseServie
    public static class Service2 extends BaseServie {
    }

    private Service1 service1;
    private Service2 service2;

    public DiAutowireByConstructor() { //@0
    }

    public DiAutowireByConstructor(Service1 service1) { //@1
        System.out.println("DiAutowireByConstructor(Service1 service1)");
        this.service1 = service1;
    }

    public DiAutowireByConstructor(Service1 service1, Service2 service2) { //@2
        System.out.println("DiAutowireByConstructor(Service1 service1, Service2 service2)");
        this.service1 = service1;
        this.service2 = service2;
    }

    public void setService1(Service1 service1) {
        this.service1 = service1;
    }

    public void setService2(Service2 service2) {
        this.service2 = service2;
    }

    @Override
    public String toString() {
        return "DiAutowireByConstructor{" +
                "service1=" + service1 +
                ", service2=" + service2 +
                '}';
    }

}

运行结果: 很明显他是使用了 public DiAutowireByConstructor(Service1 service1, Service2 service2) 构造器
在这里插入图片描述
4.1.4autowire=default
bean xml的根元素为beans,注意根元素有个default-autowire属性,这个属性可选值有(no|byName|byType|constructor|default),这个属性可以批量设置当前文件中所有bean的自动注入的方式,bean元素中如果省略了autowire属性,就相当于是autowire=default,那么会取default-autowire的值作为其autowire的值,而每个bean元素还可以单独设置自己的autowire覆盖default-autowire的配置,如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd" default-autowire="byName">

</beans>

4.1.4.1 例子:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd" default-autowire="byName">

    <bean id="service1" class="com.gzl.cn.bean.DiAutowireByConstructor.Service1">
        <property name="desc" value="service1"/>
    </bean>
    <bean id="service2" class="com.gzl.cn.bean.DiAutowireByConstructor.Service2">
        <property name="desc" value="service2"/>
    </bean>

    <bean id="diAutowireByConstructor" class="com.gzl.cn.bean.DiAutowireByConstructor" autowire="default"/>
</beans>

public class DiAutowireByConstructor {

    public static class BaseServie {
        private String desc;

        public void setDesc(String desc) {
            this.desc = desc;
        }

        @Override
        public String toString() {
            return "BaseServie{" +
                    "desc='" + desc + '\'' +
                    '}';
        }
    }

    // Service1实现了IService1接口,还继承了BaseServie
    public static class Service1 extends BaseServie {

    }

    // Service1实现了IService1接口,还继承了BaseServie
    public static class Service2 extends BaseServie {
    }

    private Service1 service1;
    private Service2 service2;

    public DiAutowireByConstructor() { //@0
    }

    public DiAutowireByConstructor(Service1 service1) { //@1
        System.out.println("DiAutowireByConstructor(Service1 service1)");
        this.service1 = service1;
    }

    public DiAutowireByConstructor(Service1 service1, Service2 service2) { //@2
        System.out.println("DiAutowireByConstructor(Service1 service1, Service2 service2)");
        this.service1 = service1;
        this.service2 = service2;
    }

    public void setService1(Service1 service1) {
        System.out.println("setService1执行了");
        this.service1 = service1;
    }

    public void setService2(Service2 service2) {
        System.out.println("setService2执行了");
        this.service2 = service2;
    }

    @Override
    public String toString() {
        return "DiAutowireByConstructor{" +
                "service1=" + service1 +
                ", service2=" + service2 +
                '}';
    }

}

运行结果:default-autowire设置的是byName,然后bean标签设置的是autowire=“default”,运行结果如下
在这里插入图片描述
4.1.5autowire=no
设置为no的时候他就不会随着default-autowire来自动配置了

不适用自动装配,只是用ref进行装配注入

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd" default-autowire="byName">

    <bean id="service1" class="com.gzl.cn.bean.DiAutowireByConstructor.Service1">
        <property name="desc" value="service1"/>
    </bean>
    <bean id="service2" class="com.gzl.cn.bean.DiAutowireByConstructor.Service2">
        <property name="desc" value="service2"/>
    </bean>

    <bean id="diAutowireByConstructor" class="com.gzl.cn.bean.DiAutowireByConstructor" autowire="no"/>
</beans>

运行结果:

在这里插入图片描述

4.2.autowireByName方法:

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

		// 当前Bean中能进行自动注入的属性名
		String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
		// 遍历每个属性名,并去获取Bean对象,并设置到pvs中
		for (String propertyName : propertyNames) {
			if (containsBean(propertyName)) {
				Object bean = getBean(propertyName);
				pvs.add(propertyName, bean);
				// 记录一下propertyName对应的Bean被beanName给依赖了
				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");
				}
		}
		}
	}

4.2.1 unsatisfiedNonSimpleProperties方法:获取当前Bean中能进行自动注入的属性名

protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
   // 用于保存结果,TreeSet可以保证有序且去重
   Set<String> result = new TreeSet<>();
   // 获取当前bean的属性值列表
   PropertyValues pvs = mbd.getPropertyValues();
   // 通过 BeanWrapper 获取当前 bean 的属性描述符数组。就是所有有set和get方法的属性
   PropertyDescriptor[] pds = bw.getPropertyDescriptors();
   for (PropertyDescriptor pd : pds) {
      // 符合以下四个条件的,就可以视作未被注入的非简单属性
      // 1. 属性具有setter方法  getWriteMethod =setter
      // 2. 属性不在依赖检查的排除列表中
      // 3. 属性在当前bean的属性值为空
      // 4. 属性类型不是简单类型
      if (pd.getWriteMethod() != null && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) &&
            !BeanUtils.isSimpleProperty(pd.getPropertyType())) {
         result.add(pd.getName());//getName是PropertyDescriptor的父类的方法 返回属性的name
      }
   }
   return StringUtils.toStringArray(result);
}

这里的PropertyDescriptor是属性描述器(javaBean),一个属性如果是private(baseName)然后有get(readMethodName)、set(writeMethodName)方法,那么java/spring就会认为是一个属性,这里是通过BeanWrapper获取(里面进行的对类的包装)。另外这里条件isSimpleProperty是判断简单类型spring是不会管的

4.2.1.1 PropertyDescriptor数据类型:

用法:
一个 PropertyDescriptor 描述了一个 Java Bean 通过一对访问器方法(getter 和 setter)所导出的属性。
代码:

public class PropertyDescriptor extends FeatureDescriptor {
    private String writeMethodName;
    private String readMethodName;

 public synchronized Class<?> getPropertyType() {
        Class<?> type = getPropertyType0();
        if (type  == null) {
            try {
                type = findPropertyType(getReadMethod(), getWriteMethod());
                setPropertyType(type);
            } catch (IntrospectionException ex) {
                // Fall
            }
        }
        return type;
    }

    private void setPropertyType(Class<?> type) {
        this.propertyTypeRef = getWeakReference(type);
    }

    private Class<?> getPropertyType0() {
        return (this.propertyTypeRef != null)
                ? this.propertyTypeRef.get()
                : null;
    }
}

效果:

在这里插入图片描述
在这里插入图片描述

每个类都默认一个class属性,这个没有set方法:此时pds中的0是class
在这里插入图片描述


4.3 autowireByType方法:

	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);

		// 当前Bean中能进行自动注入的属性名
		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.
				if (Object.class != pd.getPropertyType()) {
					MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
					
					// eager表示立即初始化,表示在根据类型查找Bean时,允不允许进行Bean的创建,如果当前bean实现了PriorityOrdered,那么则不允许
					// 为什么不允许,因为我自己是PriorityOrdered,是优先级最高的,不能有比我创建得更早的
					boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);
					DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
					// 根据类型找到的结果
					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);
			}
		}
	}


4.3.1 AutowireByTypeDependencyDescriptor数据类型:

将methodParam封装成AutowireByTypeDependencyDescriptor并赋值给desc对象,通过调用resolveDependency()方法,根据desc的依赖类型解析出与descriptor所包装的对象匹配的候选Bean对象

	private static class AutowireByTypeDependencyDescriptor extends DependencyDescriptor {

		public AutowireByTypeDependencyDescriptor(MethodParameter methodParameter, boolean eager) {
			super(methodParameter, false, eager);
		}

		@Override
		public String getDependencyName() {
			return null;
		}
	}

4.3.1.1 super方法具体:DependencyDescriptor的构造方法

	public DependencyDescriptor(MethodParameter methodParameter, boolean required, boolean eager) {
		super(methodParameter);

		this.declaringClass = methodParameter.getDeclaringClass();
		if (methodParameter.getMethod() != null) {
			this.methodName = methodParameter.getMethod().getName();
		}
		this.parameterTypes = methodParameter.getExecutable().getParameterTypes();
		this.parameterIndex = methodParameter.getParameterIndex();
		this.containingClass = methodParameter.getContainingClass();
		this.required = required;
		this.eager = eager;
	}

4.3.1.2 DependencyDescriptor数据类型:一个属性/方法一个DependencyDescriptor

//依赖所在的声明类
private final Class<?> declaringClass;
 
//如果依赖是成员方法的某个参数,则这里记录该成员方法的名称
private String methodName;
 
//如果包装的是成员方法的某个参数,则这里记录该参数的类型
private Class<?>[] parameterTypes;
 
//如果包装的是成员方法的某个参数,则这里记录该参数在该函数参数列表中的索引
private int parameterIndex;
 
//成员属性的名称
private String fieldName;
 
//是否必要依赖
private final boolean required;
 
//是否需要饥饿加载
private final boolean eager;
 
//嵌套级别
private int nestingLevel = 1;
 
//依赖的包含者类,通常和声明类是同一个
private Class<?> containingClass;

4.3.1.2.1 结合测试代码看一下:

User 类和 Friend 类,User 中注入 Friend 对象

@Component
public class User {
 
    @Autowired
    private Friend friend;
 
    @Override
    public String toString() {
        return "User{" +
                "friend=" + friend +
                '}';
    }
}
 
@Component
public class Friend {
 
    private String name = "friend";
 
    @Override
    public String toString() {
        return "Friend{" +
                "name='" + name + ''' +
                '}';
    }
}

测试:

/**
 * 测试 Bean 依赖注入的处理,进行源码调试
 *
 * @author ConstXiong
 */
public class Test {
 
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("constxiong");
        User user = context.getBean(User.class);
        System.out.println(user);
    }
}

在这里插入图片描述

4.3.2 resolveDependency方法(重点)

支持 Optional、延迟注入、懒加载注入、正常注入。

	public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
			@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
		// 用来获取方法入参名字的
		descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());

		// 所需要的类型是Optional
		if (Optional.class == descriptor.getDependencyType()) {
			return createOptionalDependency(descriptor, requestingBeanName);
		}
		// 所需要的的类型是ObjectFactory,或ObjectProvider
		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 {
			// 在属性或set方法上使用了@Lazy注解,那么则构造一个代理对象并返回,真正使用该代理对象时才进行类型筛选Bean
			Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
					descriptor, requestingBeanName);

			if (result == null) {
				// descriptor表示某个属性或某个set方法
				// requestingBeanName表示正在进行依赖注入的Bean
				result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
			}
			return result;
		}
	}


前四种场景(Optional,延迟注入 ObjectProvider + @Lazy),我们先放一下,重点分析一下最基本的使用场景,Spring 是如何进行依赖查找的 - doResolveDependency。其实无论是什么场景,最底层都是调用 doResolveDependency。

4.3.2.1 getParameterNameDiscoverer方法:

DefaultParameterNameDiscoverer是ParameterNameDiscoverer 的实现类

	private ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();

	public ParameterNameDiscoverer getParameterNameDiscoverer() {
		return this.parameterNameDiscoverer;
	}

4.3.2.1.1 ParameterNameDiscoverer接口 数据类型:

这个 Spring 用于寻找发现方法和构造函数的参数名的发现器。

/**
 * Interface to discover parameter names for methods and constructors.
 * <p>用于发现方法和构造函数的参数名的接口</p>
 * <p>
 *     参数名并非总是可以发现参数名称,但可以尝试各种策略,比如寻找在编译时可能
 *     发生调试信号,和寻找可选的附带AspectJ注解方法的argname注解值
 * </p>
 * @author Rod Johnson
 * @author Adrian Colyer
 * @since 2.0
 */
public interface ParameterNameDiscoverer {

	/*
	 *     返回方法的参数名,如果不能确定就返回{@code null}
	 * </p>
	 * <p>Individual entries in the array may be {@code null} if parameter names are only
	 * available for some parameters of the given method but not for others. However,
	 * it is recommended to use stub parameter names instead wherever feasible.
	 * <p>
	 *     如果参数名称仅可用于给定方法的某些参数,而不适用于其他参数,则数组的各个条目
	 *     可能为{@code null}.但是,建议在可行的地方使用存根参数名名代替。
	 * </p>
	 * @param method the method to find parameter names for
	 *               -- 查找参数名称的方法
	 * @return an array of parameter names if the names can be resolved,
	 * or {@code null} if they cannot
	 * 			-- 如果名称能被解析就返回一组参数名,否则返回{@code null}
	 */
	@Nullable
	String[] getParameterNames(Method method);

	
	  //   返回构造函数的参数名,如果不能确定就返回{@code null}
     //    如果参数名称仅可用于给定方法的某些参数,而不适用于其他参数,则数组的各个条目
	 //   可能为{@code null}.但是,建议在可行的地方使用存根参数名名代替。
	/*
	 * @param ctor the constructor to find parameter names for
	 *             -- 查找参数名称的方法
	 * @return an array of parameter names if the names can be resolved,
	 * or {@code null} if they cannot
	 * 				-- 如果名称能被解析就返回一组参数名,否则返回{@code null}
	 */
	@Nullable
	String[] getParameterNames(Constructor<?> ctor);

}


4.3.2.2 initParameterNameDiscovery方法:

	public void initParameterNameDiscovery(@Nullable ParameterNameDiscoverer parameterNameDiscoverer) {
		if (this.methodParameter != null) {
			this.methodParameter.initParameterNameDiscovery(parameterNameDiscoverer);
		}
	}
	//下一个用到的this.methodParameter.initParameterNameDiscovery
	public void initParameterNameDiscovery(@Nullable ParameterNameDiscoverer parameterNameDiscoverer) {
		this.parameterNameDiscoverer = parameterNameDiscoverer;
	}

4.3.2.3 doResolveDependency方法:

在依赖查找之前,想办法快速查找,如缓存 beanName、@Value 等直接获取注入的值,避免通过类型查找,最后才对集合依赖和单一依赖分别进行了处理。实际上,无论是集合依赖还是单一依赖查找都是调用 findAutowireCandidates 方法。
具体过程:

1.快速查找: @Autowired 注解处理场景。AutowiredAnnotationBeanPostProcessor 处理 @Autowired 注解时,如果注入的对象只有一个,会将该 bean 对应的名称缓存起来,下次直接通过名称查找会快很多。

2.注入指定值:@Value 注解处理场景。QualifierAnnotationAutowireCandidateResolver 处理 @Value 注解时,会读取 @Value 对应的值进行注入。如果是 String 要经过三个过程:①占位符处理 -> ②EL 表达式解析
-> ③类型转换,这也是一般的处理过程,BeanDefinitionValueResolver 处理 String 对象也是这个过程。

3.集合依赖查询:直接全部委托给 resolveMultipleBeans 方法。

4.单个依赖查询:先调用 findAutowireCandidates 查找所有可用的依赖,如果有多个依赖,则根据规则匹配: @Primary -> @Priority -> ③方法名称或字段名称。




public Object doResolveDependency(DependencyDescriptor descriptor, String beanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
 
    InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
    try {
        // 1. 快速查找,根据名称查找。AutowiredAnnotationBeanPostProcessor用到
        Object shortcut = descriptor.resolveShortcut(this);
        if (shortcut != null) {
            return shortcut;
        }
 
        // 2. 注入指定值,QualifierAnnotationAutowireCandidateResolver解析@Value会用到
        //从descriptor中获取属性类型
        Class<?> type = descriptor.getDependencyType();
        Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
        if (value != null) {
            if (value instanceof String) {
                // 2.1 占位符解析
                String strVal = resolveEmbeddedValue((String) value);
                BeanDefinition bd = (beanName != null && containsBean(beanName) ?
                                     getMergedBeanDefinition(beanName) : null);
                // 2.2 Spring EL 表达式
                value = evaluateBeanDefinitionString(strVal, bd);
            }
            TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
            try {
                // 2.3 类型转换
                return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
            } catch (UnsupportedOperationException ex) {
                return (descriptor.getField() != null ?
                        converter.convertIfNecessary(value, type, descriptor.getField()) :
                        converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
            }
        }
 
        // 3. 集合依赖,如 Array、List、Set、Map。内部查找依赖也是使用findAutowireCandidates
        Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
        if (multipleBeans != null) {
            return multipleBeans;
        }
 
        // 4. 单个依赖查询
        Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
        // 4.1 没有查找到依赖,判断descriptor.require
        if (matchingBeans.isEmpty()) {
            if (isRequired(descriptor)) {
                raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
            }
            return null;
        }
 
        String autowiredBeanName;
        Object instanceCandidate;
 
        // 4.2 有多个,如何过滤
        if (matchingBeans.size() > 1) {
            // 4.2.1 @Primary -> @Priority -> 方法名称或字段名称匹配 
            autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
            // 4.2.2 根据是否必须,抛出异常。注意这里如果是集合处理,则返回null
            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();
        }
 
        // 4.3 到了这,说明有且仅有命中一个
        if (autowiredBeanNames != null) {
            autowiredBeanNames.add(autowiredBeanName);
        }
        // 4.4 实际上调用 getBean(autowiredBeanName, type)。但什么情况下会出现这种场景?
        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);
    }
}

	
		


我们重点看一下单个依赖的查询,弄明白了单个依赖的查询,其它集合依赖也差不多。

1.查找容器中所有可用依赖:findAutowireCandidates 方法根据类型查找依赖。

2.如何有多个依赖怎么处理?其实 Spring 有一套通用的流程,先按 @Primary 查找,再按 @Priority,最后按方法名称或字段名称查找,直到只有一个 bean 为止。相关的匹配规则见determineAutowireCandidate 方法。

3.此时只有一个依赖,从容器获取真实的 bean。descriptor.resolveCandidate 方法根据名称 autowiredBeanName 实例化对象。

根据上面的分析,resolveDependency 方法对 Optional、延迟注入、懒加载注入等分别进行了处理。之后 doResolveDependency 在正式查找之前看能不能快速查找,如缓存 beanName、@Value 等快速指定需要注入的值,避免通过类型查找,最后才对集合依赖和单一依赖分别进行了处理。实际上,无论是集合依赖还是单一依赖查找,本质上都是调用 findAutowireCandidates 进行类型依赖查找。

4.3.2.3.1 findAutowireCandidates方法:

findAutowireCandidates 大致可以分为三步:先查找内部依赖,再根据类型查找,最后没有可注入的依赖则进行补偿。

1.查找内部依赖:Spring IoC 容器本身相关依赖,这部分内容是用户而言是透明的,也不用感知。resolvableDependencies 集合中注册如 BeanFactory、ApplicationContext 、ResourceLoader、ApplicationEventPublisher 等。

2.根据类型查找:包括 ①外部托管 Bean ②注册 BeanDefinition。类型查找调用 beanFactory#beanNamesForType 方法,详见 Spring IoC 依赖查找之类型自省。我们来看一下如何过滤的。

01.自身引用:isSelfReference 方法判断 beanName 和 candidate 是否是同一个对象,包括两种情况:一是名称完全相同,二是 candidate 对应的工厂对象创建了 beanName。

02.是否可以注入:底层实际调用 resolver.isAutowireCandidate 方法进行过滤,包含三重规则:①bd.autowireCandidate=true -> ②泛型匹配 ->
③@Qualifier。下面会详细介绍这个方法。

3.补偿机制:如果依赖查找无法匹配,怎么办?Spring 提供了两种补偿机制:一是泛型补偿,允许注入对象对象的泛型无法解析,二是自身引用补偿,对这两种机制使用如下:

01.先使用泛型补偿,不允许自身引用:即 fallbackDescriptor。此时如果是集合依赖,对象必须是 @Qualifier 类型。
02.允许泛型补偿和自身引用补偿:但如果是集合依赖,必须过滤自己本身,即 beanName.equals(candidate) 必须剔除。

	/** Map from dependency type to corresponding autowired value. */
	private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<>(16);




	protected Map<String, Object> findAutowireCandidates(
			@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {

		// 从BeanFactory中找出和requiredType所匹配的beanName,仅仅是beanName,这些bean不一定经过了实例化,只有到最终确定某个Bean了,如果这个Bean还没有实例化才会真正进行实例化
		String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
				this, requiredType, true, descriptor.isEager());
		Map<String, Object> result = CollectionUtils.newLinkedHashMap(candidateNames.length);

		// 根据类型从resolvableDependencies中匹配Bean,resolvableDependencies中存放的是类型:Bean对象,比如BeanFactory.class:BeanFactory对象,在Spring启动时设置
		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) {
			// 如果不是自己,则判断该candidate到底能不能用来进行自动注入
			if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
				addCandidateEntry(result, candidate, descriptor, requiredType);
			}
		}

		// 为空要么是真的没有匹配的,要么是匹配的自己
		if (result.isEmpty()) {
			// 需要匹配的类型是不是Map、数组之类的
			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);
				}
			}

			// 匹配的是自己,被自己添加到result中
			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;
	}


resolveMultipleBeans方法:

	private Object resolveMultipleBeans(DependencyDescriptor descriptor, @Nullable String beanName,
			@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) {

		final Class<?> type = descriptor.getDependencyType();
		// 如果是 StreamDependencyDescriptor 类型,则返回流的形式
		if (descriptor instanceof StreamDependencyDescriptor) {
			Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
			if (autowiredBeanNames != null) {
				autowiredBeanNames.addAll(matchingBeans.keySet());
			}
			Stream<Object> stream = matchingBeans.keySet().stream()
					.map(name -> descriptor.resolveCandidate(name, type, this))
					.filter(bean -> !(bean instanceof NullBean));
			if (((StreamDependencyDescriptor) descriptor).isOrdered()) {
				stream = stream.sorted(adaptOrderComparator(matchingBeans));
			}
			return stream;
		}	
		// 如果是 数组类型
		else if (type.isArray()) {
			// 确定最终类型
			Class<?> componentType = type.getComponentType();
			ResolvableType resolvableType = descriptor.getResolvableType();
			Class<?> resolvedArrayType = resolvableType.resolve(type);
			if (resolvedArrayType != type) {
				componentType = resolvableType.getComponentType().resolve();
			}
			if (componentType == null) {
				return null;
			}
			// 根据属性类型找到 beanFactory 中所有类型的匹配bean
			// 返回值构成 : key= 匹配的beanName, value= beanName对应的实例化bean,通过 getBean(beanName)获取。
			Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType,
					new MultiElementDescriptor(descriptor));
			// 如果是未找到匹配的bean,则返回null,
			if (matchingBeans.isEmpty()) {
				return null;
			}
			// 保存所有适配的 beanName
			if (autowiredBeanNames != null) {
				autowiredBeanNames.addAll(matchingBeans.keySet());
			}
			// 进行类型转换,将bean 转换为对应的type 类型。
			TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
			Object result = converter.convertIfNecessary(matchingBeans.values(), resolvedArrayType);
			if (result instanceof Object[]) {
				Comparator<Object> comparator = adaptDependencyComparator(matchingBeans);
				if (comparator != null) {
					// 排序
					Arrays.sort((Object[]) result, comparator);
				}
			}
			return result;
		}
		// 对 Collection 类型的处理,逻辑基本同上,这里不再赘述
		else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
			Class<?> elementType = descriptor.getResolvableType().asCollection().resolveGeneric();
			if (elementType == null) {
				return null;
			}
			Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType,
					new MultiElementDescriptor(descriptor));
			if (matchingBeans.isEmpty()) {
				return null;
			}
			if (autowiredBeanNames != null) {
				autowiredBeanNames.addAll(matchingBeans.keySet());
			}
			TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
			Object result = converter.convertIfNecessary(matchingBeans.values(), type);
			if (result instanceof List) {
				if (((List<?>) result).size() > 1) {
					Comparator<Object> comparator = adaptDependencyComparator(matchingBeans);
					if (comparator != null) {
						((List<?>) result).sort(comparator);
					}
				}
			}
			return result;
		}
		// 对map类型的处理,逻辑类似上面
		else if (Map.class == type) {
			ResolvableType mapType = descriptor.getResolvableType().asMap();
			Class<?> keyType = mapType.resolveGeneric(0);
			if (String.class != keyType) {
				return null;
			}
			Class<?> valueType = mapType.resolveGeneric(1);
			if (valueType == null) {
				return null;
			}
			Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType,
					new MultiElementDescriptor(descriptor));
			if (matchingBeans.isEmpty()) {
				return null;
			}
			if (autowiredBeanNames != null) {
				autowiredBeanNames.addAll(matchingBeans.keySet());
			}
			return matchingBeans;
		}
		else {
			return null;
		}
	}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值