之前Spring中的自动注入(byName,byType)和@Autowired注解的工作原理以及源码分析,那么今天这节课,我们来分析还没讲完的,剩下的核心的方法:
- @Nullable
- Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
- @Nullable Set
autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException;
该方法表示,传入一个依赖描述(DependencyDescriptor),该方法会根据该依赖描述从BeanFactory中找出对应的唯一的一个Bean对象。
下面来分析一下DefaultListableBeanFactory中**resolveDependency()**方法的具体实现,具体流程图:
Spring中根据Type找Bean的流程| ProcessOn免费在线作图,在线流程图,在线思维导图
根据类型找beanName的底层流程:根据类型找beanName的底层流程| ProcessOn免费在线作图,在线流程图,在线思维导图
对应执行流程图为:依赖注入流程| ProcessOn免费在线作图,在线流程图,在线思维导图
首先在Java反射中,有一个Type接口,表示类型,具体分类为:
大家可以好好看看下面代码所打印的结果:
- public class TypeTest<T> {
-
- private int i;
- private Integer it;
- private int[] iarray;
- private List list;
- private List
slist; - private List
tlist; - private T t;
- private T[] tarray;
-
- public static void main(String[] args) throws NoSuchFieldException {
-
- test(TypeTest.class.getDeclaredField("i"));
- System.out.println("=======");
- test(TypeTest.class.getDeclaredField("it"));
- System.out.println("=======");
- test(TypeTest.class.getDeclaredField("iarray"));
- System.out.println("=======");
- test(TypeTest.class.getDeclaredField("list"));
- System.out.println("=======");
- test(TypeTest.class.getDeclaredField("slist"));
- System.out.println("=======");
- test(TypeTest.class.getDeclaredField("tlist"));
- System.out.println("=======");
- test(TypeTest.class.getDeclaredField("t"));
- System.out.println("=======");
- test(TypeTest.class.getDeclaredField("tarray"));
-
- }
-
- public static void test(Field field) {
-
- if (field.getType().isPrimitive()) {
- System.out.println(field.getName() + "是基本数据类型");
- } else {
- System.out.println(field.getName() + "不是基本数据类型");
- }
-
- if (field.getGenericType() instanceof ParameterizedType) {
- System.out.println(field.getName() + "是泛型类型");
- } else {
- System.out.println(field.getName() + "不是泛型类型");
- }
-
- if (field.getType().isArray()) {
- System.out.println(field.getName() + "是普通数组");
- } else {
- System.out.println(field.getName() + "不是普通数组");
- }
-
- if (field.getGenericType() instanceof GenericArrayType) {
- System.out.println(field.getName() + "是泛型数组");
- } else {
- System.out.println(field.getName() + "不是泛型数组");
- }
-
- if (field.getGenericType() instanceof TypeVariable) {
- System.out.println(field.getName() + "是泛型变量");
- } else {
- System.out.println(field.getName() + "不是泛型变量");
- }
-
- }
-
- }
Spring中,但注入点是一个泛型时,也是会进行处理的,比如:
- @Component
- public class UserService extends BaseService<OrderService, StockService> {
-
- public void test() {
- System.out.println(o);
- }
-
- }
-
- public class BaseService<O, S> {
-
- @Autowired
- protected O o;
-
- @Autowired
- protected S s;
- }
userService.getClass().getGenericSuperclass().getTypeName()
获取到具体的泛型信息,比如com.zhouyu.service.BaseService
for (TypeVariable extends Class>> typeParameter : userService.getClass().getSuperclass().getTypeParameters()) { System._out_.println(typeParameter.getName()); }
oField.getGenericType()
就知道当前field使用的是哪个泛型,就能知道具体类型了
定义两个注解:
- @Target({ElementType.TYPE, ElementType.FIELD})
- @Retention(RetentionPolicy.RUNTIME)
- @Qualifier("random")
- public @interface Random {
- }
- @Target({ElementType.TYPE, ElementType.FIELD})
- @Retention(RetentionPolicy.RUNTIME)
- @Qualifier("roundRobin")
- public @interface RoundRobin {
- }
定义一个接口和两个实现类,表示负载均衡:
- public interface LoadBalance {
- String select();
- }
- @Component
- @Random
- public class RandomStrategy implements LoadBalance {
-
- @Override
- public String select() {
- return null;
- }
- }
- @Component
- @RoundRobin
- public class RoundRobinStrategy implements LoadBalance {
-
- @Override
- public String select() {
- return null;
- }
- }
使用:
- @Component
- public class UserService {
-
- @Autowired
- @RoundRobin
- private LoadBalance loadBalance;
-
- public void test() {
- System.out.println(loadBalance);
- }
-
- }
@Resource注解底层工作流程图:
@Resource注解底层工作原理| ProcessOn免费在线作图,在线流程图,在线思维导图