Análisis del código fuente subyacente de la inyección de dependencia de Spring (2)

Análisis del código fuente subyacente de la inyección de dependencia de Spring

  • BeanFactory#resolveDependency
    • El proceso subyacente de encontrar frijoles por tipo en Spring
  • PredeterminadoListableBeanFactory#findAutowireCandidates
    • Encuentre el proceso subyacente de beanName según el tipo en Spring
  • Proceso de inyección de dependencia
  • @Uso de calificador
  • @Resource anota el flujo de trabajo subyacente

BeanFactory#resolveDependency

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

Este método indica que se pasa una descripción de dependencia DependencyDescriptor, y el método encontrará el objeto Bean único correspondiente de BeanFactory de acuerdo con la descripción de dependencia.

Podemos analizar la implementación específica del método DefaultListableBeanFactory#resolveDependency de la clase de implementación BeanFactory

El proceso subyacente de encontrar frijoles por tipo en Spring

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. Determinar el tipo de dependencia.

      1. Si es Opcional, llame a doResolveDependency

      2. Si es ObjectFactory u ObjectProvider, llame a doResolveDependency cuando llame al método ObjectFactory#getObject

      3. Si hay una anotación @Lazy en la dependencia, entonces se generará y devolverá un objeto proxy, luego se llamará a doResolveDependency cuando se llame al método en el objeto proxy.

  2. La lógica de ejecución para el doResolveDependency anterior es la siguiente

    1. Determinar si existe la anotación @Value
      1. Si existe, obtenga y analice la anotación @Value en el descriptor, analícela y devuelva
      2. Determinar el tipo de descriptor
        1. Si el tipo correspondiente al descriptor es una matriz, mapa, etc., no es necesario filtrar más el método que coincide con el tipo correspondiente al 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;
}
复制代码

Supongo que te gusta

Origin juejin.im/post/7088679647973474335
Recomendado
Clasificación