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