sprng boot 工程 读取不到依赖jar的配置文件, 本地idea跑没问题,但是在服务器却读取失败(appassembler打包方式)

spring boot 工程有一个依赖工程xxx-common.jar, 这个xxx-common.jar有一个工具类XUtils,这个工具类会读取xxx-common.jar classpath下的一个配置文件。
本来XUtils.class.getResource("/xxxx.json").getPath();获取路径,读取这个配置文件信息。后来发现服务器上跑有问题。(我这边的打包方式是appassembler方式)。

后来记得spring-boot 源码里面有 自动装配下读取有 spring.factory的文件, 后来参考了一下源码。

关键地方 org.springframework.util.ClassUtils getDefaultClassLoader 方法;

//源码如下:

public static ClassLoader getDefaultClassLoader() {
		ClassLoader cl = null;
		try {
			cl = Thread.currentThread().getContextClassLoader();
		}
		catch (Throwable ex) {
			// Cannot access thread context ClassLoader - falling back...
		}
		if (cl == null) {
			// No thread context class loader -> use class loader of this class.
			cl = ClassUtils.class.getClassLoader();
			if (cl == null) {
				// getClassLoader() returning null indicates the bootstrap ClassLoader
				try {
					cl = ClassLoader.getSystemClassLoader();
				}
				catch (Throwable ex) {
					// Cannot access system ClassLoader - oh well, maybe the caller can live with null...
				}
			}
		}
		return cl;
	}

后来使用一下的方式读取成功:

    ClassUtils.getDefaultClassLoader().getResourceAsStream("xxx.json");

#应该对应的就是下面的代码

	Thread.currentThread().getContextClassLoader().getResourceAsStream("xxx.json");

XUtils.class.getResource("/xxxx.json") 或者 XUtils.class.getClassLoader.getResource("/xxxx.json") 都是主工程的classpath 。

并且这配置文件是处于jar里面的, 直接通过path好像还不能访问, 所以使用了 getResourceAsStream。

spring-boot 还有挺多细节可以看看的(关键代码 ConfigurationClassPostProcessor.class、 AutoConfigurationImportSelector.class )


public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
		PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {

	private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();//loadFactoryNames方法的 classLoader 
}



protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,
			AnnotationAttributes attributes) {
		List<String> configurations = SpringFactoriesLoader.loadFactoryNames(
				getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
		Assert.notEmpty(configurations,
				"No auto configuration classes found in META-INF/spring.factories. If you "
						+ "are using a custom packaging, make sure that file is correct.");
		return configurations;
	}



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 propertyValue = properties.getProperty(factoryClassName);
				for (String factoryName : StringUtils.commaDelimitedListToStringArray(propertyValue)) {
					result.add(factoryName.trim());
				}
			}
			return result;
		}
		catch (IOException ex) {
			throw new IllegalArgumentException("Unable to load factories from location [" +
					FACTORIES_RESOURCE_LOCATION + "]", ex);
		}
	}

你可能感兴趣的:(sprng boot 工程 读取不到依赖jar的配置文件, 本地idea跑没问题,但是在服务器却读取失败(appassembler打包方式))