zoukankan      html  css  js  c++  java
  • Spring-boot实例化流程

    在spring-boot项目中pom文件里面添加的依赖中的bean,是如何注册到spring-boot项目的spring容器中的呢?

    spring.factories文件

    • 帮助spring-boot项目包以外的bean(即在pom文件中添加依赖中的bean)注册到spring-boot项目的spring容器的
    • 由于@ComponentScan注解只能扫描spring-boot项目包内的bean并注册到spring容器中
    • 因此需要@EnableAutoConfiguration(在SpringBootApplication下)注解来注册项目包外的bean
    • 而spring.factories文件,则是用来记录项目包外需要注册的bean类名

    点进去@SpringBootApplication注解

    //
    // Source code recreated from a .class file by IntelliJ IDEA
    // (powered by FernFlower decompiler)
    //
    
    package org.springframework.boot.autoconfigure;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Inherited;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    import org.springframework.boot.SpringBootConfiguration;
    import org.springframework.boot.context.TypeExcludeFilter;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.FilterType;
    import org.springframework.context.annotation.ComponentScan.Filter;
    import org.springframework.core.annotation.AliasFor;
    
    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @SpringBootConfiguration
    @EnableAutoConfiguration
    @ComponentScan(
        excludeFilters = {@Filter(
        type = FilterType.CUSTOM,
        classes = {TypeExcludeFilter.class}
    ), @Filter(
        type = FilterType.CUSTOM,
        classes = {AutoConfigurationExcludeFilter.class}
    )}
    )
    public @interface SpringBootApplication {
        @AliasFor(
            annotation = EnableAutoConfiguration.class
        )
        Class<?>[] exclude() default {};
    
        @AliasFor(
            annotation = EnableAutoConfiguration.class
        )
        String[] excludeName() default {};
    
        @AliasFor(
            annotation = ComponentScan.class,
            attribute = "basePackages"
        )
        String[] scanBasePackages() default {};
    
        @AliasFor(
            annotation = ComponentScan.class,
            attribute = "basePackageClasses"
        )
        Class<?>[] scanBasePackageClasses() default {};
    
        @AliasFor(
            annotation = Configuration.class
        )
        boolean proxyBeanMethods() default true;
    }

    点@EnableAutoConfiguration进去

    //
    // Source code recreated from a .class file by IntelliJ IDEA
    // (powered by FernFlower decompiler)
    //
    
    package org.springframework.boot.autoconfigure;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Inherited;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    import org.springframework.context.annotation.Import;
    
    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @AutoConfigurationPackage
    @Import({AutoConfigurationImportSelector.class})
    public @interface EnableAutoConfiguration {
        String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
    
        Class<?>[] exclude() default {};
    
        String[] excludeName() default {};
    }

    点AutoConfigurationImportSelector进去

    //
    // Source code recreated from a .class file by IntelliJ IDEA
    // (powered by FernFlower decompiler)
    //
    
    package org.springframework.boot.autoconfigure;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Collection;
    import java.util.Collections;
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.LinkedHashMap;
    import java.util.LinkedHashSet;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    import java.util.concurrent.TimeUnit;
    import java.util.stream.Collectors;
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.Aware;
    import org.springframework.beans.factory.BeanClassLoaderAware;
    import org.springframework.beans.factory.BeanFactory;
    import org.springframework.beans.factory.BeanFactoryAware;
    import org.springframework.beans.factory.NoSuchBeanDefinitionException;
    import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
    import org.springframework.boot.context.properties.bind.Binder;
    import org.springframework.context.EnvironmentAware;
    import org.springframework.context.ResourceLoaderAware;
    import org.springframework.context.annotation.DeferredImportSelector;
    import org.springframework.context.annotation.DeferredImportSelector.Group;
    import org.springframework.context.annotation.DeferredImportSelector.Group.Entry;
    import org.springframework.core.Ordered;
    import org.springframework.core.annotation.AnnotationAttributes;
    import org.springframework.core.env.ConfigurableEnvironment;
    import org.springframework.core.env.Environment;
    import org.springframework.core.io.ResourceLoader;
    import org.springframework.core.io.support.SpringFactoriesLoader;
    import org.springframework.core.type.AnnotationMetadata;
    import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
    import org.springframework.core.type.classreading.MetadataReaderFactory;
    import org.springframework.util.Assert;
    import org.springframework.util.ClassUtils;
    import org.springframework.util.StringUtils;
    
    public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
        private static final AutoConfigurationImportSelector.AutoConfigurationEntry EMPTY_ENTRY = new AutoConfigurationImportSelector.AutoConfigurationEntry();
        private static final String[] NO_IMPORTS = new String[0];
        private static final Log logger = LogFactory.getLog(AutoConfigurationImportSelector.class);
        private static final String PROPERTY_NAME_AUTOCONFIGURE_EXCLUDE = "spring.autoconfigure.exclude";
        private ConfigurableListableBeanFactory beanFactory;
        private Environment environment;
        private ClassLoader beanClassLoader;
        private ResourceLoader resourceLoader;
    
        public AutoConfigurationImportSelector() {
        }
    
        public String[] selectImports(AnnotationMetadata annotationMetadata) {
            if (!this.isEnabled(annotationMetadata)) {
                return NO_IMPORTS;
            } else {
                AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
                AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);
                return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
            }
        }
    
        protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata, AnnotationMetadata annotationMetadata) {
            if (!this.isEnabled(annotationMetadata)) {
                return EMPTY_ENTRY;
            } else {
                AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
                List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
                configurations = this.removeDuplicates(configurations);
                Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
                this.checkExcludedClasses(configurations, exclusions);
                configurations.removeAll(exclusions);
                configurations = this.filter(configurations, autoConfigurationMetadata);
                this.fireAutoConfigurationImportEvents(configurations, exclusions);
                return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
            }
        }
    
        public Class<? extends Group> getImportGroup() {
            return AutoConfigurationImportSelector.AutoConfigurationGroup.class;
        }
    
        protected boolean isEnabled(AnnotationMetadata metadata) {
            return this.getClass() == AutoConfigurationImportSelector.class ? (Boolean)this.getEnvironment().getProperty("spring.boot.enableautoconfiguration", Boolean.class, true) : true;
        }
    
        protected AnnotationAttributes getAttributes(AnnotationMetadata metadata) {
            String name = this.getAnnotationClass().getName();
            AnnotationAttributes attributes = AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(name, true));
            Assert.notNull(attributes, () -> {
                return "No auto-configuration attributes found. Is " + metadata.getClassName() + " annotated with " + ClassUtils.getShortName(name) + "?";
            });
            return attributes;
        }
    
        protected Class<?> getAnnotationClass() {
            return EnableAutoConfiguration.class;
        }
    
        protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
            List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.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;
        }
    
        protected Class<?> getSpringFactoriesLoaderFactoryClass() {
            return EnableAutoConfiguration.class;
        }
    
        private void checkExcludedClasses(List<String> configurations, Set<String> exclusions) {
            List<String> invalidExcludes = new ArrayList(exclusions.size());
            Iterator var4 = exclusions.iterator();
    
            while(var4.hasNext()) {
                String exclusion = (String)var4.next();
                if (ClassUtils.isPresent(exclusion, this.getClass().getClassLoader()) && !configurations.contains(exclusion)) {
                    invalidExcludes.add(exclusion);
                }
            }
    
            if (!invalidExcludes.isEmpty()) {
                this.handleInvalidExcludes(invalidExcludes);
            }
    
        }
    
        protected void handleInvalidExcludes(List<String> invalidExcludes) {
            StringBuilder message = new StringBuilder();
            Iterator var3 = invalidExcludes.iterator();
    
            while(var3.hasNext()) {
                String exclude = (String)var3.next();
                message.append("	- ").append(exclude).append(String.format("%n"));
            }
    
            throw new IllegalStateException(String.format("The following classes could not be excluded because they are not auto-configuration classes:%n%s", message));
        }
    
        protected Set<String> getExclusions(AnnotationMetadata metadata, AnnotationAttributes attributes) {
            Set<String> excluded = new LinkedHashSet();
            excluded.addAll(this.asList(attributes, "exclude"));
            excluded.addAll(Arrays.asList(attributes.getStringArray("excludeName")));
            excluded.addAll(this.getExcludeAutoConfigurationsProperty());
            return excluded;
        }
    
        private List<String> getExcludeAutoConfigurationsProperty() {
            if (this.getEnvironment() instanceof ConfigurableEnvironment) {
                Binder binder = Binder.get(this.getEnvironment());
                return (List)binder.bind("spring.autoconfigure.exclude", String[].class).map(Arrays::asList).orElse(Collections.emptyList());
            } else {
                String[] excludes = (String[])this.getEnvironment().getProperty("spring.autoconfigure.exclude", String[].class);
                return excludes != null ? Arrays.asList(excludes) : Collections.emptyList();
            }
        }
    
        private List<String> filter(List<String> configurations, AutoConfigurationMetadata autoConfigurationMetadata) {
            long startTime = System.nanoTime();
            String[] candidates = StringUtils.toStringArray(configurations);
            boolean[] skip = new boolean[candidates.length];
            boolean skipped = false;
            Iterator var8 = this.getAutoConfigurationImportFilters().iterator();
    
            while(var8.hasNext()) {
                AutoConfigurationImportFilter filter = (AutoConfigurationImportFilter)var8.next();
                this.invokeAwareMethods(filter);
                boolean[] match = filter.match(candidates, autoConfigurationMetadata);
    
                for(int i = 0; i < match.length; ++i) {
                    if (!match[i]) {
                        skip[i] = true;
                        candidates[i] = null;
                        skipped = true;
                    }
                }
            }
    
            if (!skipped) {
                return configurations;
            } else {
                List<String> result = new ArrayList(candidates.length);
    
                int numberFiltered;
                for(numberFiltered = 0; numberFiltered < candidates.length; ++numberFiltered) {
                    if (!skip[numberFiltered]) {
                        result.add(candidates[numberFiltered]);
                    }
                }
    
                if (logger.isTraceEnabled()) {
                    numberFiltered = configurations.size() - result.size();
                    logger.trace("Filtered " + numberFiltered + " auto configuration class in " + TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime) + " ms");
                }
    
                return new ArrayList(result);
            }
        }
    
        protected List<AutoConfigurationImportFilter> getAutoConfigurationImportFilters() {
            return SpringFactoriesLoader.loadFactories(AutoConfigurationImportFilter.class, this.beanClassLoader);
        }
    
        protected final <T> List<T> removeDuplicates(List<T> list) {
            return new ArrayList(new LinkedHashSet(list));
        }
    
        protected final List<String> asList(AnnotationAttributes attributes, String name) {
            String[] value = attributes.getStringArray(name);
            return Arrays.asList(value);
        }
    
        private void fireAutoConfigurationImportEvents(List<String> configurations, Set<String> exclusions) {
            List<AutoConfigurationImportListener> listeners = this.getAutoConfigurationImportListeners();
            if (!listeners.isEmpty()) {
                AutoConfigurationImportEvent event = new AutoConfigurationImportEvent(this, configurations, exclusions);
                Iterator var5 = listeners.iterator();
    
                while(var5.hasNext()) {
                    AutoConfigurationImportListener listener = (AutoConfigurationImportListener)var5.next();
                    this.invokeAwareMethods(listener);
                    listener.onAutoConfigurationImportEvent(event);
                }
            }
    
        }
    
        protected List<AutoConfigurationImportListener> getAutoConfigurationImportListeners() {
            return SpringFactoriesLoader.loadFactories(AutoConfigurationImportListener.class, this.beanClassLoader);
        }
    
        private void invokeAwareMethods(Object instance) {
            if (instance instanceof Aware) {
                if (instance instanceof BeanClassLoaderAware) {
                    ((BeanClassLoaderAware)instance).setBeanClassLoader(this.beanClassLoader);
                }
    
                if (instance instanceof BeanFactoryAware) {
                    ((BeanFactoryAware)instance).setBeanFactory(this.beanFactory);
                }
    
                if (instance instanceof EnvironmentAware) {
                    ((EnvironmentAware)instance).setEnvironment(this.environment);
                }
    
                if (instance instanceof ResourceLoaderAware) {
                    ((ResourceLoaderAware)instance).setResourceLoader(this.resourceLoader);
                }
            }
    
        }
    
        public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
            Assert.isInstanceOf(ConfigurableListableBeanFactory.class, beanFactory);
            this.beanFactory = (ConfigurableListableBeanFactory)beanFactory;
        }
    
        protected final ConfigurableListableBeanFactory getBeanFactory() {
            return this.beanFactory;
        }
    
        public void setBeanClassLoader(ClassLoader classLoader) {
            this.beanClassLoader = classLoader;
        }
    
        protected ClassLoader getBeanClassLoader() {
            return this.beanClassLoader;
        }
    
        public void setEnvironment(Environment environment) {
            this.environment = environment;
        }
    
        protected final Environment getEnvironment() {
            return this.environment;
        }
    
        public void setResourceLoader(ResourceLoader resourceLoader) {
            this.resourceLoader = resourceLoader;
        }
    
        protected final ResourceLoader getResourceLoader() {
            return this.resourceLoader;
        }
    
        public int getOrder() {
            return 2147483646;
        }
    
        protected static class AutoConfigurationEntry {
            private final List<String> configurations;
            private final Set<String> exclusions;
    
            private AutoConfigurationEntry() {
                this.configurations = Collections.emptyList();
                this.exclusions = Collections.emptySet();
            }
    
            AutoConfigurationEntry(Collection<String> configurations, Collection<String> exclusions) {
                this.configurations = new ArrayList(configurations);
                this.exclusions = new HashSet(exclusions);
            }
    
            public List<String> getConfigurations() {
                return this.configurations;
            }
    
            public Set<String> getExclusions() {
                return this.exclusions;
            }
        }
    
        private static class AutoConfigurationGroup implements Group, BeanClassLoaderAware, BeanFactoryAware, ResourceLoaderAware {
            private final Map<String, AnnotationMetadata> entries = new LinkedHashMap();
            private final List<AutoConfigurationImportSelector.AutoConfigurationEntry> autoConfigurationEntries = new ArrayList();
            private ClassLoader beanClassLoader;
            private BeanFactory beanFactory;
            private ResourceLoader resourceLoader;
            private AutoConfigurationMetadata autoConfigurationMetadata;
    
            private AutoConfigurationGroup() {
            }
    
            public void setBeanClassLoader(ClassLoader classLoader) {
                this.beanClassLoader = classLoader;
            }
    
            public void setBeanFactory(BeanFactory beanFactory) {
                this.beanFactory = beanFactory;
            }
    
            public void setResourceLoader(ResourceLoader resourceLoader) {
                this.resourceLoader = resourceLoader;
            }
    
            public void process(AnnotationMetadata annotationMetadata, DeferredImportSelector deferredImportSelector) {
                Assert.state(deferredImportSelector instanceof AutoConfigurationImportSelector, () -> {
                    return String.format("Only %s implementations are supported, got %s", AutoConfigurationImportSelector.class.getSimpleName(), deferredImportSelector.getClass().getName());
                });
                AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector)deferredImportSelector).getAutoConfigurationEntry(this.getAutoConfigurationMetadata(), annotationMetadata);
                this.autoConfigurationEntries.add(autoConfigurationEntry);
                Iterator var4 = autoConfigurationEntry.getConfigurations().iterator();
    
                while(var4.hasNext()) {
                    String importClassName = (String)var4.next();
                    this.entries.putIfAbsent(importClassName, annotationMetadata);
                }
    
            }
    
            public Iterable<Entry> selectImports() {
                if (this.autoConfigurationEntries.isEmpty()) {
                    return Collections.emptyList();
                } else {
                    Set<String> allExclusions = (Set)this.autoConfigurationEntries.stream().map(AutoConfigurationImportSelector.AutoConfigurationEntry::getExclusions).flatMap(Collection::stream).collect(Collectors.toSet());
                    Set<String> processedConfigurations = (Set)this.autoConfigurationEntries.stream().map(AutoConfigurationImportSelector.AutoConfigurationEntry::getConfigurations).flatMap(Collection::stream).collect(Collectors.toCollection(LinkedHashSet::new));
                    processedConfigurations.removeAll(allExclusions);
                    return (Iterable)this.sortAutoConfigurations(processedConfigurations, this.getAutoConfigurationMetadata()).stream().map((importClassName) -> {
                        return new Entry((AnnotationMetadata)this.entries.get(importClassName), importClassName);
                    }).collect(Collectors.toList());
                }
            }
    
            private AutoConfigurationMetadata getAutoConfigurationMetadata() {
                if (this.autoConfigurationMetadata == null) {
                    this.autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
                }
    
                return this.autoConfigurationMetadata;
            }
    
            private List<String> sortAutoConfigurations(Set<String> configurations, AutoConfigurationMetadata autoConfigurationMetadata) {
                return (new AutoConfigurationSorter(this.getMetadataReaderFactory(), autoConfigurationMetadata)).getInPriorityOrder(configurations);
            }
    
            private MetadataReaderFactory getMetadataReaderFactory() {
                try {
                    return (MetadataReaderFactory)this.beanFactory.getBean("org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory", MetadataReaderFactory.class);
                } catch (NoSuchBeanDefinitionException var2) {
                    return new CachingMetadataReaderFactory(this.resourceLoader);
                }
            }
        }
    }

    selectImports方法

    public String[] selectImports(AnnotationMetadata annotationMetadata) {
            if (!this.isEnabled(annotationMetadata)) {
                return NO_IMPORTS;
            } else {
                AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
                AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);
                return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
            }
        }

    执行此方法时,向spring ioc容器注入bean

    selectImports,返回bean全名

    import将bean全名注入

    注入的bean都是什么

    点getAutoConfigurationEntry进去

    protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata, AnnotationMetadata annotationMetadata) {
            if (!this.isEnabled(annotationMetadata)) {
                return EMPTY_ENTRY;
            } else {
                AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
                List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
                configurations = this.removeDuplicates(configurations);
                Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
                this.checkExcludedClasses(configurations, exclusions);
                configurations.removeAll(exclusions);
                configurations = this.filter(configurations, autoConfigurationMetadata);
                this.fireAutoConfigurationImportEvents(configurations, exclusions);
                return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
            }
        }

    点getCandidateConfigurations进去

    protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
        List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.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;
    }

    点SpringFactoriesLoader进去

    //
    // Source code recreated from a .class file by IntelliJ IDEA
    // (powered by FernFlower decompiler)
    //
    
    package org.springframework.core.io.support;
    
    import java.io.IOException;
    import java.net.URL;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Enumeration;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    import java.util.Properties;
    import java.util.Map.Entry;
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.springframework.core.annotation.AnnotationAwareOrderComparator;
    import org.springframework.core.io.UrlResource;
    import org.springframework.lang.Nullable;
    import org.springframework.util.Assert;
    import org.springframework.util.ClassUtils;
    import org.springframework.util.ConcurrentReferenceHashMap;
    import org.springframework.util.LinkedMultiValueMap;
    import org.springframework.util.MultiValueMap;
    import org.springframework.util.ReflectionUtils;
    import org.springframework.util.StringUtils;
    
    public final class SpringFactoriesLoader {
        public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
        private static final Log logger = LogFactory.getLog(SpringFactoriesLoader.class);
        private static final Map<ClassLoader, MultiValueMap<String, String>> cache = new ConcurrentReferenceHashMap();
    
        private SpringFactoriesLoader() {
        }
    
        public static <T> List<T> loadFactories(Class<T> factoryType, @Nullable ClassLoader classLoader) {
            Assert.notNull(factoryType, "'factoryType' must not be null");
            ClassLoader classLoaderToUse = classLoader;
            if (classLoader == null) {
                classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
            }
    
            List<String> factoryImplementationNames = loadFactoryNames(factoryType, classLoaderToUse);
            if (logger.isTraceEnabled()) {
                logger.trace("Loaded [" + factoryType.getName() + "] names: " + factoryImplementationNames);
            }
    
            List<T> result = new ArrayList(factoryImplementationNames.size());
            Iterator var5 = factoryImplementationNames.iterator();
    
            while(var5.hasNext()) {
                String factoryImplementationName = (String)var5.next();
                result.add(instantiateFactory(factoryImplementationName, factoryType, classLoaderToUse));
            }
    
            AnnotationAwareOrderComparator.sort(result);
            return result;
        }
    
        public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
            String factoryTypeName = factoryType.getName();
            return (List)loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
        }
    
        private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
            MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
            if (result != null) {
                return result;
            } else {
                try {
                    Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
                    LinkedMultiValueMap result = new LinkedMultiValueMap();
    
                    while(urls.hasMoreElements()) {
                        URL url = (URL)urls.nextElement();
                        UrlResource resource = new UrlResource(url);
                        Properties properties = PropertiesLoaderUtils.loadProperties(resource);
                        Iterator var6 = properties.entrySet().iterator();
    
                        while(var6.hasNext()) {
                            Entry<?, ?> entry = (Entry)var6.next();
                            String factoryTypeName = ((String)entry.getKey()).trim();
                            String[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
                            int var10 = var9.length;
    
                            for(int var11 = 0; var11 < var10; ++var11) {
                                String factoryImplementationName = var9[var11];
                                result.add(factoryTypeName, factoryImplementationName.trim());
                            }
                        }
                    }
    
                    cache.put(classLoader, result);
                    return result;
                } catch (IOException var13) {
                    throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var13);
                }
            }
        }
    
        private static <T> T instantiateFactory(String factoryImplementationName, Class<T> factoryType, ClassLoader classLoader) {
            try {
                Class<?> factoryImplementationClass = ClassUtils.forName(factoryImplementationName, classLoader);
                if (!factoryType.isAssignableFrom(factoryImplementationClass)) {
                    throw new IllegalArgumentException("Class [" + factoryImplementationName + "] is not assignable to factory type [" + factoryType.getName() + "]");
                } else {
                    return ReflectionUtils.accessibleConstructor(factoryImplementationClass, new Class[0]).newInstance();
                }
            } catch (Throwable var4) {
                throw new IllegalArgumentException("Unable to instantiate factory class [" + factoryImplementationName + "] for factory type [" + factoryType.getName() + "]", var4);
            }
        }
    }

    发现一个常量:FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";

    所有外在的jar包都是通过对应jar包下的这个路径加载配置并实例化的

    论读书
    睁开眼,书在面前
    闭上眼,书在心里
  • 相关阅读:
    web测试--安全性
    web测试--链接测试
    web测试--兼容性
    web测试--界面和易用性
    web测试--返回键、回车键、刷新键
    web测试--查询结果
    列表标签代码解析
    备份
    java格式化时间
    js往div里添加table
  • 原文地址:https://www.cnblogs.com/YC-L/p/14476347.html
Copyright © 2011-2022 走看看