首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么使用spring.factories进行Spring自动配置而不是注释?

为什么使用spring.factories进行Spring自动配置而不是注释?
EN

Stack Overflow用户
提问于 2015-08-20 00:10:39
回答 4查看 24.8K关注 0票数 35

这些文件指出:

开发自动配置和使用条件 如果您在开发共享库的公司工作,或者在开源或商业库上工作,您可能需要开发自己的自动配置。自动配置类可以打包在外部jars中,并且仍然可以通过Spring来获取。

如果我对其他所有内容都有注释(偶数@AutoConfigureAfter或@AutoConfigureBefore注解),

为什么要维护一个属性文件来指向带有注释的类?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-08-20 05:42:40

因为我们不会扫描世界,找出在您的项目中存在哪些自动配置类。首先,自动配置只是一个普通的@Configuration类.

Spring组件的查找方式是通过显式声明或组件扫描,但是在实际启动上下文之前,我们需要知道自动配置类的列表。

票数 45
EN

Stack Overflow用户

发布于 2019-05-30 13:01:37

当SpringBoot应用程序启动时,它不会扫描jars中的所有类,因此SpringBoot初学者应该指定哪些类是自动配置的。例如,在spring 2.0.4中,example初始化如下:

代码语言:javascript
运行
复制
@SpringBootApplication
public class MyApplication {
    public static void main(String[] args) {
       //1. method run will call the construtor below
        SpringApplication.run(MyApplication.class, args);
    }
}

    public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
        this.resourceLoader = resourceLoader;
        Assert.notNull(primarySources, "PrimarySources must not be null");
        this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
        this.webApplicationType = deduceWebApplicationType();
        //2. find all the classes whose key is ApplicationContextInitializer in spring.factories and initialize them 
        setInitializers((Collection) getSpringFactoriesInstances(
                ApplicationContextInitializer.class));
        setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
        this.mainApplicationClass = deduceMainApplicationClass();
    }

...
    private <T> Collection<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<>(
                //3. use current thread classcloader to load resources in the classpath
                SpringFactoriesLoader.loadFactoryNames(type, classLoader));
        List<T> instances = createSpringFactoriesInstances(type, parameterTypes,
                classLoader, args, names);
        AnnotationAwareOrderComparator.sort(instances);
        return instances;
    }

//SpringFactoriesLoader.java
public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {
        String factoryClassName = factoryClass.getName();
        // 3.1  first find the configuration file
        return loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
    }

private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
        ...
        try {
            Enumeration<URL> urls = (classLoader != null ?
            //  public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories"; 
            //4. spring.factories file is defined here
                    classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
                    ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
            result = new LinkedMultiValueMap<>();
            ...
    }
票数 1
EN

Stack Overflow用户

发布于 2020-02-17 19:57:40

spring.factories中的所有条目都通过以下方法加载-

org.springframework.boot.autoconfigure.ImportAutoConfigurationImportSelector#loadFactoryNames

代码语言:javascript
运行
复制
protected Collection<String> loadFactoryNames(Class<?> source) {
        return SpringFactoriesLoader.loadFactoryNames(source, getClass().getClassLoader());
    }

SpringFactoriesLoader属于spring核心库,见下面的屏幕快照

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32107610

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档