003--SpringBoot如何实现自动配置

2018-05-14  本文已影响10人  糖纸疯了

SpringBoot在SpringApplication创建对象实例的时候,会默认读取 "META-INF/spring.factories" 中信息,然后将该文件中的配置信息载入到Spring

setInitializers((Collection) getSpringFactoriesInstances(
ApplicationContextInitializer.class));

    @SuppressWarnings({ "unchecked", "rawtypes" })
    private void initialize(Object[] sources) {
        if (sources != null && sources.length > 0) {
            this.sources.addAll(Arrays.asList(sources));
        }
        this.webEnvironment = deduceWebEnvironment();
        setInitializers((Collection) getSpringFactoriesInstances(
                ApplicationContextInitializer.class));
        setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
        this.mainApplicationClass = deduceMainApplicationClass();
    }

SpringFactoriesLoader.loadFactoryNames(type, classLoader));

    private <T> Collection<? extends T> getSpringFactoriesInstances(Class<T> type,
            Class<?>[] parameterTypes, Object... args) {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        // Use names and ensure unique to protect against duplicates
        Set<String> names = new LinkedHashSet<String>(
                SpringFactoriesLoader.loadFactoryNames(type, classLoader));
        List<T> instances = createSpringFactoriesInstances(type, parameterTypes,
                classLoader, args, names);
        AnnotationAwareOrderComparator.sort(instances);
        return instances;
    }

classLoader.getResources("META-INF/spring.factories")

    public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
        String factoryClassName = factoryClass.getName();
        try {
            Enumeration urls = (classLoader != null)
                    ? classLoader.getResources("META-INF/spring.factories")
                    : ClassLoader.getSystemResources("META-INF/spring.factories");

            List result = new ArrayList();
            while (urls.hasMoreElements()) {
                URL 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 [" + "META-INF/spring.factories" + "]", ex);
        }
    }
上一篇 下一篇

猜你喜欢

热点阅读