@ConditionOnMissingBean顺序问题

本文探讨了在SpringBoot环境中,当多个jar包都注入了相同类的Bean时,如何通过@Order注解和SpringFactoriesLoader机制来确定哪个Bean会被加载。详细分析了SpringFactoriesLoader的源码,解释了其如何自动扫描所有jar包下的实现并进行排序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

当多个jar包下,都注入了同一个类

//jar1
@Bean
@ConditionalOnMissingBean
@Order
fun teac1():Teac=Teac("qwww",12)

//jar2
@Bean
@Order(Ordered.LOWEST_PRECEDENCE-1)
@ConditionalOnMissingBean
fun teac2():Teac=Teac("dddd",13)

一般我们使用SpringFactories,在META-INF/spring.factories下用org.springframework.boot.autoconfigure.EnableAutoConfiguration实现spring容器扫描,此时那个jar包下的bean会生效呢?

看SpringFactoriesLoader源码

public static <T> List<T> loadFactories(Class<T> factoryClass, ClassLoader classLoader) {
	  Assert.notNull(factoryClass, "'factoryClass' must not be null");
	ClassLoader classLoaderToUse = classLoader;
	if (classLoaderToUse == null) {
		classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
	}
	List<String> factoryNames = loadFactoryNames(factoryClass, classLoaderToUse);
	if (logger.isTraceEnabled()) {
		logger.trace("Loaded [" + factoryClass.getName() + "] names: " + factoryNames);
	}
	List<T> result = new ArrayList<T>(factoryNames.size());
	for (String factoryName : factoryNames) {
		result.add(instantiateFactory(factoryName, factoryClass, classLoaderToUse));
	}
	AnnotationAwareOrderComparator.sort(result);
	return result;
  }

factoryClass为EnableAutoConfiguration.class会自动扫描所有jar包下的实现,并由AnnotationAwareOrderComparator排序,所以我们在自己的autoconfig上配置@order即可

/**
 * Load the fully qualified class names of factory implementations of the
 * given type from {@value #FACTORIES_RESOURCE_LOCATION}, using the given
 * class loader.
 * @param factoryClass the interface or abstract class representing the factory
 * @param classLoader the ClassLoader to use for loading resources; can be
 * {@code null} to use the default
 * @see #loadFactories
 * @throws IllegalArgumentException if an error occurs while loading factory names
 */
public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
	String factoryClassName = factoryClass.getName();
	try {
		Enumeration<URL> urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
				ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
		List<String> result = new ArrayList<String>();
		while (urls.hasMoreElements()) {
			URL url = urls.nextElement();
			Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
			String factoryClassNames = properties.getProperty(factoryClassName);
			result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));
		}
		return result;
	}
	catch (IOException ex) {
		throw new IllegalArgumentException("Unable to load [" + factoryClass.getName() +
				"] factories from location [" + FACTORIES_RESOURCE_LOCATION + "]", ex);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值