Spring之依赖注入底层源码解析(二)

Spring之依赖注入底层源码解析

  • BeanFactory#resolveDependency
    • Spring中根据类型找Bean的底层流程
  • DefaultListableBeanFactory#findAutowireCandidates
    • Spring中根据类型找beanName底层流程
  • 依赖注入流程
  • @Qualifier使用
  • @Resource注解底层工作流程

BeanFactory#resolveDependency

@Nullable
Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
		@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException;
复制代码

该方法表示,传入一个依赖描述DependencyDescriptor,该方法会根据依赖描述从BeanFactory中找出对应的唯一的一个Bean对象

我们可以分析一下BeanFactory的实现类DefaultListableBeanFactory#resolveDependency方法的具体实现

Spring中根据类型找Bean的底层流程

public Object resolveDependency(DependencyDescriptor descriptor, @Nullable St
		@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typ
	// 用来获取方法入参名字的
	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, reque
	}
	else {
		// 在属性或set方法上使用了@Lazy注解,那么则构造一个代理对象并返回,真正使用该代理对象时才进行类型筛选Bean
		Object result = getAutowireCandidateResolver().getLazyResolutionProxy
				descriptor, requestingBeanName);
		if (result == null) {
			// descriptor表示某个属性或某个set方法
			// requestingBeanName表示正在进行依赖注入的Bean
			result = doResolveDependency(descriptor, requestingBeanName, auto
		}
		return result;
	}
}     
复制代码
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
		@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansExce
	InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
	try {
		// 如果当前descriptor之前做过依赖注入了,则可以直接取shortcut了,相当于缓存
		Object shortcut = descriptor.resolveShortcut(this);
		if (shortcut != null) {
			return shortcut;
		}
		Class<?> type = descriptor.getDependencyType();
		// 获取@Value所指定的值 看方法参数,字段名有没有
		Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
		if (value != null) {
			if (value instanceof String) {
				// 占位符填充(${})
				String strVal = resolveEmbeddedValue((String) value);
				BeanDefinition bd = (beanName != null && containsBean(beanName) ?
						getMergedBeanDefinition(beanName) : null);
				// 解析Spring表达式(#{})
				value = evaluateBeanDefinitionString(strVal, bd);
			}
			// 将value转化为descriptor所对应的类型 如果想让123赋值给一个对象,默认是做不了的,需要类型转换器
			TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
			try {
				return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
			}
			catch (UnsupportedOperationException ex) {
				// A custom TypeConverter which does not support TypeDescriptor resolution...
				return (descriptor.getField() != null ?
						converter.convertIfNecessary(value, type, descriptor.getField()) :
						converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
			}
		}
		// 如果descriptor所对应的类型是数组、Map这些,就将descriptor对应的类型所匹配的所有bean方法,不用进一步做筛选了
		Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConvert
		if (multipleBeans != null) {
			return multipleBeans;
		}
		// 找到所有Bean,key是beanName, value有可能是bean对象,有可能是beanClass --> 比较核心
		Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
		// 找到的Bean是空的->expected at least 1 bean which qualifies as autowire candidate
		if (matchingBeans.isEmpty()) {
			// required为true,抛异常
			if (isRequired(descriptor)) {
				raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
			}
			return null;
		}
		String autowiredBeanName;
		Object instanceCandidate;
		// 找到了多个
		if (matchingBeans.size() > 1) {
			// 根据类型找到了多个Bean,进一步筛选出某一个, @Primary-->优先级最高--->name
			autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
			if (autowiredBeanName == null) {
				if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
					return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
				}
				else {
					// In case of an optional Collection/Map, silently ignore a non-unique case:
					// possibly it was meant to be an empty collection of multiple regular beans
					// (before 4.3 in particular when we didn't even look for collection beans).
					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();
		}
		// 记录匹配过的beanName
		if (autowiredBeanNames != null) {
			autowiredBeanNames.add(autowiredBeanName);
		}
		// 有可能筛选出来的是某个bean的类型,此处就进行实例化,调用getBean
		if (instanceCandidate instanceof Class) {
			instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
		}
		Object result = instanceCandidate;
		// @Bean的时候返回的是null,最后放到单例池的是NullBean
		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);
	}
}
复制代码
        
@Nullable
private Object resolveMultipleBeans(DependencyDescriptor descriptor, @Nullable String beanNam
		@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) {
	Class<?> type = descriptor.getDependencyType();
	if (descriptor instanceof StreamDependencyDescriptor) {
		// 找到type所匹配的所有bean
		Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor
		if (autowiredBeanNames != null) {
			autowiredBeanNames.addAll(matchingBeans.keySet());
		}
		// 构造成一个stream
		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;
		}
		// 根据数组元素类型找到所匹配的所有Bean
		Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType,
				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(), resolvedArrayTyp
		if (result instanceof Object[]) {
			Comparator<Object> comparator = adaptDependencyComparator(matchingBeans);
			if (comparator != null) {
				Arrays.sort((Object[]) result, comparator);
			}
		}
		return result;
	}
	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;
	}
	else if (Map.class == type) {
		ResolvableType mapType = descriptor.getResolvableType().asMap();
		Class<?> keyType = mapType.resolveGeneric(0);
		// 如果Map的key不是String
		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;
	}
}   
复制代码

Spring中根据Type找Bean的流程.png

  1. 调用DefaultListableBeanFactory#resolveDependency

    1. 判断依赖的类型

      1. 如果是Optional,调用doResolveDependency

      2. 如果是ObjectFactory或ObjectProvider,在调用ObjectFactory#getObject方法时调用doResolveDependency

      3. 如果依赖上有@Lazy注解.那么就会生成一个代理对象然后返回,那么在调用代理对象中的方法时调用doResolveDependency

  2. 对于上面的doResolveDependency执行逻辑如下

    1. 判断是否存在@Value注解
      1. 如果存在,获取并且解析descriptor上的@Value注解,进行解析后并且返回
      2. 判断descriptor的类型
        1. 如果descriptor所对应的类型是数组、Map这些,就将descriptor对应的类型所匹配的方法不用进一步做筛选了
        2. 调用findAutowireCandidate,findAutowireCandidate该方法会返回一个Map,表示会根据类型去找Bean,Map的key为beanName,Map的value为对象,对于value可能是Bean对象也可能是某Bean的class对象,因为该方法只负责根据类型找到对应的Bean,如果该Bean还没有实例化,那么该方法不负责去实例化,只会返回Bean对应的Class对象,表示这个Bean也是结果之一
        3. 根据类型看有没有找到Bean
          1. 如果找到了只有一个,就直接返回该Bean,如果是Class对象,就会调用getBean生成该Bean对象
          2. 如果超过一个
            1. 从多个Bean中选择被@Primary标注了的Bean,如果有多个@Primary会报错
            2. 如果没有@Primary,那么就看Bean上是否通过@Priority定义了优先级,如果定义了就获取优先级最高的Bean
            3. 如果没有优先级,那么就使用descriptor.getDependencyName来确定唯一的Bean
              1. 是否找出唯一的一个Bean
                1. 找出了,也会判断是否是Class对象,如果是,就调用getBean方法去生成Bean对象,然后返回
                2. 如果没找到,判断isReuquired如果是true就报错,否则返回null
        4. 如果没找到,判断isReuquired如果是true就报错,否则返回null

DefaultListableBeanFactory#findAutowireCandidates

Spring中根据类型找beanName底层流程

	String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
				this, requiredType, true, descriptor.isEager());
复制代码
public static String[] beanNamesForTypeIncludingAncestors(
		ListableBeanFactory lbf, Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
	Assert.notNull(lbf, "ListableBeanFactory must not be null");
	// 从本容器中找
	String[] result = lbf.getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
	// 从父容器找并放入result
	if (lbf instanceof HierarchicalBeanFactory) {
		HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf;
		if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) {
			String[] parentResult = beanNamesForTypeIncludingAncestors(
					(ListableBeanFactory) hbf.getParentBeanFactory(), type, includeNonSingletons, allowEagerInit);
			result = mergeNamesWithParent(result, parentResult, hbf);
		}
	}
	return result;
}
复制代码
public String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
	// 如果没有冻结,就根据类型去BeanFactory找,如果冻结了,可能就跳过这个if然后去缓存中去拿了
	if (!isConfigurationFrozen() || type == null || !allowEagerInit) {
		return doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, allowEagerInit);
	}
	// 把当前类型所匹配的beanName缓存起来
	Map<Class<?>, String[]> cache =
			(includeNonSingletons ? this.allBeanNamesByType : this.singletonBeanNamesByType);
	String[] resolvedBeanNames = cache.get(type);
	if (resolvedBeanNames != null) {
		return resolvedBeanNames;
	}
	resolvedBeanNames = doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, true);
	if (ClassUtils.isCacheSafe(type, getBeanClassLoader())) {
		cache.put(type, resolvedBeanNames);
	}
	return resolvedBeanNames;
}
复制代码
private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
	List<String> result = new ArrayList<>();
	// Check all bean definitions.
	// 遍历所有的BeanDefinitions
	for (String beanName : this.beanDefinitionNames) {
		// Only consider bean as eligible if the bean name is not defined as alias for some other bean.
		if (!isAlias(beanName)) {
			try {
				RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				// Only check bean definition if it is complete.
				// 判断mbd允不允许获取对应类型
				// 首先mdb不能是抽象的,然后allowEagerInit为true,则直接去推测mdb的类型,并进行匹配
				// 如果allowEagerInit为false,那就继续判断,如果mdb还没有加载类并且是懒加载的并且不允许提前加载类,那mbd不能用来进行匹配(因为不允许提前加载类,只能在此mdb自己去创建bean对象时
				// 如果allowEagerInit为false,并且mbd已经加载类了,或者是非懒加载的,或者允许提前加载类,并且不用必须提前初始化才能获取类型,那么就可以去进行匹配了
				// 这个条件有点复杂,但是如果只考虑大部分流程,则可以忽略这个判断,因为allowEagerInit传进来的基本上都是true
				if (!mbd.isAbstract() && (allowEagerInit ||
						(mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading()) &&
								!requiresEagerInitForType(mbd.getFactoryBeanName()))) {
					boolean isFactoryBean = isFactoryBean(beanName, mbd);
					BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
					boolean matchFound = false;
					boolean allowFactoryBeanInit = (allowEagerInit || containsSingleton(beanName));
					boolean isNonLazyDecorated = (dbd != null && !mbd.isLazyInit());
					// 当前BeanDefinition不是FactoryBean,就是普通Bean
					if (!isFactoryBean) {
						// 在筛选Bean时,如果仅仅只包括单例,但是beanName对应的又不是单例,则忽略
						if (includeNonSingletons || isSingleton(beanName, mbd, dbd)) {
							matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
						}
					} else {
						if (includeNonSingletons || isNonLazyDecorated ||
								(allowFactoryBeanInit && isSingleton(beanName, mbd, dbd))) {
							matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
						}
						if (!matchFound) {
							// In case of FactoryBean, try to match FactoryBean instance itself next.
							beanName = FACTORY_BEAN_PREFIX + beanName;
							matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
						}
					}
					if (matchFound) {
						result.add(beanName);
					}
				}
			} catch (CannotLoadBeanClassException | BeanDefinitionStoreException ex) {
				if (allowEagerInit) {
					throw ex;
				}
				// Probably a placeholder: let's ignore it for type matching purposes.
				LogMessage message = (ex instanceof CannotLoadBeanClassException ?
						LogMessage.format("Ignoring bean class loading failure for bean '%s'", beanName) :
						LogMessage.format("Ignoring unresolvable metadata in bean definition '%s'", beanName));
				logger.trace(message, ex);
				// Register exception, in case the bean was accidentally unresolvable.
				onSuppressedException(ex);
			} catch (NoSuchBeanDefinitionException ex) {
				// Bean definition got removed while we were iterating -> ignore.
			}
		}
	}
}
复制代码

根据类型找beanName.png

  1. 找出BeanFactory中类型为type的所有bean的名字,注意的是名字而不是bean对象,因为我们可以根据BeanDefinition就能判断和当前type是不是匹配,不用生成Bean对象
  2. 把resolvableDependencies中key为type的对象找出来并且添加到result中
  3. 遍历根据type找出beanName,判断当前beanName对应的Bean是不是能够被自动注入
  4. 先判断beanName对应的BeanDefinition中的autowireCandidate属性,如果是false,表示不能用来进行自动注入,如果是true,就继续进行判断
  5. 判断的当前type是不是泛型,如果是泛型,会把容器中所有的beanName找出来,如果是这种情况,那么在这一步中就要获取到泛型的真正类型,然后进行匹配,如果当前beanName和当前泛型对应的真实类型匹配,那么就继续判断
  6. 如果当前DependencyDescriptor上存在@Qualifier注解,那么就要判断当前beanName上是否定义了Qualifier,并且是否和当前DependencyDescriptor上的Qualifier相等,相等就匹配
  7. 经过上述验证后,当前beanName才能成为一个可注入的,添加到result中

依赖注入流程

依赖注入流程.png

依赖注入中泛型注入的实现

首先在Java反射中,有一个Type接口,表示类型,具体分类为:

  1. raw types:也就是普通Class
  2. parameterized types:对应ParameterizedType接口,泛型类型
  3. array types:对应GenericArrayType,泛型数组
  4. type variables:对应TypeVariable接口,表示类型变量,也就是所定义的泛型,比如T、K
  5. primitive types:基本类型,int、boolean

我们可以看下下面的打印结果:

public class TypeTest<T> {

 private int i;
 private Integer it;
 private int[] iarray;
 private List list;
 private List<String> slist;
 private List<T> 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() + "不是泛型变量");
		}

	}

}
复制代码
i是基本数据类型
i不是泛型类型
i不是普通数组
i不是泛型数组
i不是泛型变量
=======
it不是基本数据类型
it不是泛型类型
it不是普通数组
it不是泛型数组
it不是泛型变量
=======
iarray不是基本数据类型
iarray不是泛型类型
iarray是普通数组
iarray不是泛型数组
iarray不是泛型变量
=======
list不是基本数据类型
list不是泛型类型
list不是普通数组
list不是泛型数组
list不是泛型变量
=======
slist不是基本数据类型
slist是泛型类型
slist不是普通数组
slist不是泛型数组
slist不是泛型变量
=======
tlist不是基本数据类型
tlist是泛型类型
tlist不是普通数组
tlist不是泛型数组
tlist不是泛型变量
=======
t不是基本数据类型
t不是泛型类型
t不是普通数组
t不是泛型数组
t是泛型变量
=======
tarray不是基本数据类型
tarray不是泛型类型
tarray是普通数组
tarray是泛型数组
tarray不是泛型变量
复制代码

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

复制代码
  1. Spring扫描时发现UserService是一个Bean

  2. 那就取出注入点,也就是BaseService中的两个属性o和s

  3. 接下来需要按注入点类型进行注入,但是o和s都是泛型,所以Spring需要确定o和s的具体类型

  4. 因为当前正在创建的是UserService的Bean,所以可以通过userService.getClass().getGenericSuperclass().getTypeName()获取到具体的泛型信息

  5. 然后再拿到UserService的父类BaseServuce泛型变量

for (TypeVariable<? extends Class<?>> typeParameter : userService.getClass().getSuperclass().getTypeParameters()) { 			System._out_.println(typeParameter.getName()); 
}
复制代码
  1. 通过上面两段代码,就能知道,o对应的具体就是OrderService,s对应的具体类型就是StockService
  2. 然后再调用oField.getGenericType()就知道当前field使用的是哪个泛型,就能知道具体类型了

Qualifier的使用

我们可以模拟实现负载均衡

@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注解底层工作流程图

@Resource工作流程.png

对于@Resouce的具体实现CommonAnnotationBeanPostProcessor#postProcessProperties

@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
	InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);
	try {
		metadata.inject(bean, beanName, pvs);
	}
	catch (Throwable ex) {
		throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);
	}
	return pvs;
}
复制代码

猜你喜欢

转载自juejin.im/post/7088679647973474335