当框架还没有启动的时候或者启动的初期,是没有能力提供完善功能的,因此需要一个机制提供初期的简陋的功能扩展,就是变种的SPI
1 约定配置文件路径
1
| public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
|
2 扫描配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
protected static Map<String, List<String>> loadFactoriesResource(ClassLoader classLoader, String resourceLocation) { Map<String, List<String>> result = new LinkedHashMap<>(); try { Enumeration<URL> urls = classLoader.getResources(resourceLocation); while (urls.hasMoreElements()) { UrlResource resource = new UrlResource(urls.nextElement()); Properties properties = PropertiesLoaderUtils.loadProperties(resource); properties.forEach((name, value) -> { String[] factoryImplementationNames = StringUtils.commaDelimitedListToStringArray((String) value); List<String> implementations = result.computeIfAbsent(((String) name).trim(), key -> new ArrayList<>(factoryImplementationNames.length)); Arrays.stream(factoryImplementationNames).map(String::trim).forEach(implementations::add); }); } result.replaceAll(SpringFactoriesLoader::toDistinctUnmodifiableList); } catch (IOException ex) { throw new IllegalArgumentException("Unable to load factories from location [" + resourceLocation + "]", ex); } return Collections.unmodifiableMap(result); }
|
3 拿着接口找实现
1 2 3 4
| private <T> List<T> getSpringFactoriesInstances(Class<T> type) { return getSpringFactoriesInstances(type, null); }
|