@Autowired原理(三)
今天接着讲@Autowired注解,对于集合以及数组的成员变量,怎么通过@Autowired的方式注入。
package com.example.springdemo.demos.a16;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.DependencyDescriptor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;import java.util.ArrayList;
import java.util.List;@Configuration
public class TestAutowired2 {public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TestAutowired2.class);DefaultListableBeanFactory factory = context.getDefaultListableBeanFactory();//1.解析数组类型的依赖注入testArray(factory);//2.解析集合类型的依赖注入testList(factory);}private static void testArray(DefaultListableBeanFactory factory) throws NoSuchFieldException {DependencyDescriptor descriptor = new DependencyDescriptor(Target.class.getDeclaredField("serviceArray"), true);if(descriptor.getDependencyType().isArray()){Class<?> componentType = descriptor.getDependencyType().getComponentType();System.out.println(componentType);String[] names = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(factory, componentType);List<Object> beans = new ArrayList<>();for (String name : names){System.out.println(name);Object bean = descriptor.resolveCandidate(name,componentType, factory);beans.add(bean);}Object array = factory.getTypeConverter().convertIfNecessary(beans, descriptor.getDependencyType());System.out.println(array);}}private static void testList(DefaultListableBeanFactory beanFactory) throws NoSuchFieldException {DependencyDescriptor dd2 = new DependencyDescriptor(Target.class.getDeclaredField("serviceList"),true);if(dd2.getDependencyType() == List.class){Class<?> resolve = dd2.getResolvableType().getGeneric().resolve();System.out.println(resolve);List<Object> list = new ArrayList<>();String[] names = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, resolve);for (String name : names){Object bean = dd2.resolveCandidate(name,resolve,beanFactory);list.add(bean);}System.out.println(list);}}@Componentstatic class Target {@Autowired private Service[] serviceArray;@Autowired private List<Service> serviceList;}interface Service{}@Component("service1")static class Service1 implements Service{private String name;}@Component("service2")static class Service2 implements Service{private String name;}@Component("service3")static class Service3 implements Service{private String name;}}
1.解析数组类型的注入
首先使用descriptor.getDependencyType()拿到变量的类型,通过descriptor.getDependencyType().getComponentType()拿到数组里面元素的类型,然后通过
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(factory, componentType)方法拿到数组里面的元素的名字。最后使用descriptor.resolveCandidate(name,componentType, factory)获取bean对象。
2.解析集合类型的注入
同样是先拿到@Autowired注解下的变量类型,判断是否是集合,使用dd2.getResolvableType().getGeneric().resolve()拿到集合里面的泛型类型,然后通过BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, resolve)拿到集合里面所有元素的名字,最后通过dd2.resolveCandidate(name,resolve,beanFactory)获取所有的bean对象。
打印结果: