Spring Factories如何实现自动配置?

2026-06-10 05:391阅读0评论SEO基础
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计2284个文字,预计阅读时间需要10分钟。

Spring Factories如何实现自动配置?

在阅读本章内容前,建议您先了解Java的SPI状态,因为Spring的Factories实际上是Spring版本的Java SPI。我在关于Java基础系列文章中详细介绍了Java SPI机制。Spring Factories最重要的功能是。

在看本节文章之前,建议大家先去了一下java的SPI状态,因为Spring的Factories就是Spring版本的Java Spi,我在关于java基础系列文章中有详细介绍Java SPI机制。 Spring Factories的最重要的功能就是:可以通过配置文件指定Spring容器加载一些特定的组件。​

基本概念

什么是Spring Factories Spring Factories是一种类似于Java SPI的机制,它在META-INF/spring.factories文件中配置接口的实现类名称,然后在程序中读取这些配置文件并实例化。

​​引用自博客​​:Java SPI 主要是应用于厂商自定义组件或插件中。在java.util.ServiceLoader的文档里有比较详细的介绍。简单的总结下java SPI机制的思想:我们系统里抽象的各个模块,往往有很多不同的实现方案,比如日志模块、xml解析模块、jdbc模块等方案。面向的对象的设计里,我们一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。一旦代码里涉及具体的实现类,就违反了可拔插的原则,如果需要替换一种实现,就需要修改代码。为了实现在模块装配的时候能不在程序里动态指明,这就需要一种服务发现机制。 Java SPI就是提供这样的一个机制:为某个接口寻找服务实现的机制。有点类似IOC的思想,就是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要。


为什么要有Spring Factories

Spring Factories机制提供了一种解耦容器注入的方式,帮助外部包(独立于spring-boot项目)注册Bean到spring boot项目容器中。

Spring Factories如何实现自动配置?

问题:如果想要被Spring容器管理的Bean的路径不再Spring Boot 项目的扫描路径下,那该怎么办呢?

普通解法1:在Spring Boot 项目中配置ComponentScan注解的扫描路径,添加需要被扫描的方法。

普通解法2:通过在Spring Boot 项目中添加@EnableAutoConfiguration注解,并自定义@EnableXXXXConfiguration的注解,通过注解中的方法注入Bean。 普通解法3:在Spring Boot项目中xxxx.................。

这些解法主要思想都如下图所示,虽然已经实现了帮助外部包(独立于spring-boot项目)注册Bean到spring boot项目容器中的功能,但是Spring Boot 项目都需要知道外部包的信息,并在其代码中引入外部包的相关逻辑,如果外部包变更的情况下,Spring Boot 项目也需要跟着变更,Spring Boot和外部包实现直接存在紧耦合关系。


Spring包依赖


Spring Factories机制解法:

在外部包的META-INF/spring.factories文件中添加配置文件,Spring Boot项目会自动扫描这个配置文件,获取外部包的Bean的详细信息。基本思想如下图所示,从图中可以看到,Spring Boot项目中已经不包含外部包的相关逻辑,实现与外部包之间的解耦关系。

Spring的SPI


Spring Factories机制原理

核心类SpringFactoriesLoader

从上文可知,Spring Factories机制通过META-INF/spring.factories文件获取相关的实现类的配置信息,而SpringFactoriesLoader的功能就是读取META-INF/spring.factories,并加载配置中的类。SpringFactoriesLoader主要有两个方法:loadFactories和loadFactoryNames。

SpringFactoriesLoader官方说明 : General purpose factory loading mechanism for internal use within the framework.

META-INF/spring.factories中定义了实现类和对应的接口之间的关系,其定义格式如下:

example.MyService=example.MyServiceImpl1,example.MyServiceImpl2 其中的example.MyService为接口全称,example.MyServiceImpl1,example.MyServiceImpl2为两个实现类的全称。


官方说明: SpringFactoriesLoader loads and instantiates factories of a given type from META-INF/spring.factories files which may be present in multiple JAR files in the classpath. The file must be in {@link Properties} format, where the key is the fully qualified name of the interface or abstract class, and the value is a comma-separated list of implementation class names. For example: example.MyService=example.MyServiceImpl1,example.MyServiceImpl2 where {@code example.MyService} is the name of the interface, and {@code MyServiceImpl1} and {@code MyServiceImpl2} are two implementations.

loadFactoryNames

在这个方法中会遍历整个ClassLoader中所有jar包下的spring.factories文件。通过Properties解析所有接口的实现类名称。

public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
String factoryTypeName = factoryType.getName();
return loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
}

loadFactories

loadFactories方法首先调用loadFactoryNames方法获取待实例化的具体实现类的全称,然后调用instantiateFactory方法实例化每一个具体实现类,最终返回一个具体实现类的实例列表。

public static <T> List<T> loadFactories(Class<T> factoryType, @Nullable ClassLoader classLoader) {
Assert.notNull(factoryType, "'factoryType' must not be null");
ClassLoader classLoaderToUse = classLoader;
if (classLoaderToUse == null) {
classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
}
//调用loadFactoryNames获取接口的实现类
List<String> factoryImplementationNames = loadFactoryNames(factoryType, classLoaderToUse);
if (logger.isTraceEnabled()) {
logger.trace("Loaded [" + factoryType.getName() + "] names: " + factoryImplementationNames);
}
//遍历 factoryNames 数组,创建实现类的对象
List<T> result = new ArrayList<>(factoryImplementationNames.size());
for (String factoryImplementationName : factoryImplementationNames) {
//调用instantiateFactory根据类创建实例对象
result.add(instantiateFactory(factoryImplementationName, factoryType, classLoaderToUse));
}
//排序
AnnotationAwareOrderComparator.sort(result);
return result;
}

Spring Boot 默认的Factories

Spring boot中默认使用了很多factories机制,主要包含:

  • ApplicationContextInitializer:用于在spring容器刷新之前初始化Spring ConfigurableApplicationContext的回调接口。
  • ApplicationListener:用于处理容器初始化各个阶段的事件。
  • AutoConfigurationImportListener:导入配置类的时候,获取类的详细信息(Listener that can be registered with spring.factories to receive details of imported auto-configurations.)。
  • AutoConfigurationImportFilter:用于按条件过滤导入的配置类(Filter that can be registered in spring.factories to limit the auto-configuration classes considered. This interface is designed to allow fast removal of auto-configuration classes before their bytecode is even read.)
  • EnableAutoConfiguration:指定自动加载的配置类列表(Enable auto-configuration of the Spring Application Context, attempting to guess and configure beans that you are likely to need. Auto-configuration classes are usually applied based on your classpath and what beans you have defined. For example, if you have tomcat-embedded.jar on your classpath you are likely to want a TomcatServletWebServerFactory (unless you have defined your own ServletWebServerFactory bean).
  • FailureAnalyzer:在启动时拦截异常并将其转换为易读的消息,并将其包含在FailureAnalysis中。 Spring Boot为应用程序上下文相关异常、JSR-303验证等提供了此类分析器(A FailureAnalyzer is used to analyze a failure and provide diagnostic information that can be displayed to the user.)
  • TemplateAvailabilityProvider:模版引擎配置。(Collection of TemplateAvailabilityProvider beans that can be used to check which (if any) templating engine supports a given view. Caches responses unless the spring.template.provider.cache property is set to false.)​

  • 自定义Spring Factories机制

    本节将使用一个例子来展示Spring Factories机制,案例分为两个项目spring-factories-provider和spring-factories-consume,其中spring-factories-consume可以类比于上文中的Spring Boot项目,包含Bean的接口和Bean的调用,spring-factories-provider可以类比于外部包,包含了bean的实现。项目目录结构如下:

    Spring Factories机制

    以下为各个文件的内容:

  • DemoService
  • @Service
    public class PrintDemoService {
    @PostConstruct
    public void printService(){
    List<String> serviceNames = SpringFactoriesLoader.loadFactoryNames(DemoService.class,null);
    for (String serviceName:serviceNames){
    System.out.println(serviceName);
    }

    List<DemoService> services = SpringFactoriesLoader.loadFactories(DemoService.class,null);
    for (DemoService demoService:services){
    demoService.printName();
    }
    }

  • PrintDemoService
  • public class DemoServiceImpl1 implements DemoService {
    @Override
    public void printName() {
    System.out.println("This is in demo 1.");
    }
    }

  • PrintDemoService
  • public class DemoServiceImpl1 implements DemoService {
    @Override
    public void printName() {
    System.out.println("This is in demo 1.");
    }
    }

  • DemoServiceImpl2
  • public class DemoServiceImpl2 implements DemoService {
    @Override
    public void printName() {
    System.out.println("This is in demo 2.");
    }
    }

  • FactoriesApplication
  • @SpringBootApplication
    public class FactoriesApplication {
    public static void main(String[] args) {
    SpringApplication.run(FactoriesApplication.class, args);
    }
    }

  • spring.factories
  • com.wangzemin.learning.factories.interfac.DemoService=\
    com.wangzemin.learning.factories.impl.DemoServiceImpl1,\
    com.wangzemin.learning.factories.impl.DemoServiceImpl2

    程序的运行结果如下图所示,可以看到,Factories机制已经成功发挥作用。

    在这里插入图片描述

    附录:spring boot 自带factories文件示例

    # Initializers
    org.springframework.context.ApplicationContextInitializer=\
    org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
    org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener

    # Application Listeners
    org.springframework.context.ApplicationListener=\
    org.springframework.boot.autoconfigure.BackgroundPreinitializer

    # Auto Configuration Import Listeners
    org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\
    org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener

    # Auto Configuration Import Filters
    org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\
    org.springframework.boot.autoconfigure.condition.OnBeanCondition,\
    org.springframework.boot.autoconfigure.condition.OnClassCondition,\
    org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition

    # Auto Configure
    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
    org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
    org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
    org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
    org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
    org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
    org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
    org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration,\
    org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
    org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
    org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
    org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRestClientAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.r2dbc.R2dbcRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.r2dbc.R2dbcTransactionManagerAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\
    org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration,\
    org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
    org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
    org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
    org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\
    org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\
    org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\
    org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\
    org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\
    org.springframework.boot.autoconfigure.blog.csdn.net/dieaixia5129/article/details/126081613​​

    ​​blog.csdn.net/curtinliu/article/details/111588917​​


    本文共计2284个文字,预计阅读时间需要10分钟。

    Spring Factories如何实现自动配置?

    在阅读本章内容前,建议您先了解Java的SPI状态,因为Spring的Factories实际上是Spring版本的Java SPI。我在关于Java基础系列文章中详细介绍了Java SPI机制。Spring Factories最重要的功能是。

    在看本节文章之前,建议大家先去了一下java的SPI状态,因为Spring的Factories就是Spring版本的Java Spi,我在关于java基础系列文章中有详细介绍Java SPI机制。 Spring Factories的最重要的功能就是:可以通过配置文件指定Spring容器加载一些特定的组件。​

    基本概念

    什么是Spring Factories Spring Factories是一种类似于Java SPI的机制,它在META-INF/spring.factories文件中配置接口的实现类名称,然后在程序中读取这些配置文件并实例化。

    ​​引用自博客​​:Java SPI 主要是应用于厂商自定义组件或插件中。在java.util.ServiceLoader的文档里有比较详细的介绍。简单的总结下java SPI机制的思想:我们系统里抽象的各个模块,往往有很多不同的实现方案,比如日志模块、xml解析模块、jdbc模块等方案。面向的对象的设计里,我们一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。一旦代码里涉及具体的实现类,就违反了可拔插的原则,如果需要替换一种实现,就需要修改代码。为了实现在模块装配的时候能不在程序里动态指明,这就需要一种服务发现机制。 Java SPI就是提供这样的一个机制:为某个接口寻找服务实现的机制。有点类似IOC的思想,就是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要。


    为什么要有Spring Factories

    Spring Factories机制提供了一种解耦容器注入的方式,帮助外部包(独立于spring-boot项目)注册Bean到spring boot项目容器中。

    Spring Factories如何实现自动配置?

    问题:如果想要被Spring容器管理的Bean的路径不再Spring Boot 项目的扫描路径下,那该怎么办呢?

    普通解法1:在Spring Boot 项目中配置ComponentScan注解的扫描路径,添加需要被扫描的方法。

    普通解法2:通过在Spring Boot 项目中添加@EnableAutoConfiguration注解,并自定义@EnableXXXXConfiguration的注解,通过注解中的方法注入Bean。 普通解法3:在Spring Boot项目中xxxx.................。

    这些解法主要思想都如下图所示,虽然已经实现了帮助外部包(独立于spring-boot项目)注册Bean到spring boot项目容器中的功能,但是Spring Boot 项目都需要知道外部包的信息,并在其代码中引入外部包的相关逻辑,如果外部包变更的情况下,Spring Boot 项目也需要跟着变更,Spring Boot和外部包实现直接存在紧耦合关系。


    Spring包依赖


    Spring Factories机制解法:

    在外部包的META-INF/spring.factories文件中添加配置文件,Spring Boot项目会自动扫描这个配置文件,获取外部包的Bean的详细信息。基本思想如下图所示,从图中可以看到,Spring Boot项目中已经不包含外部包的相关逻辑,实现与外部包之间的解耦关系。

    Spring的SPI


    Spring Factories机制原理

    核心类SpringFactoriesLoader

    从上文可知,Spring Factories机制通过META-INF/spring.factories文件获取相关的实现类的配置信息,而SpringFactoriesLoader的功能就是读取META-INF/spring.factories,并加载配置中的类。SpringFactoriesLoader主要有两个方法:loadFactories和loadFactoryNames。

    SpringFactoriesLoader官方说明 : General purpose factory loading mechanism for internal use within the framework.

    META-INF/spring.factories中定义了实现类和对应的接口之间的关系,其定义格式如下:

    example.MyService=example.MyServiceImpl1,example.MyServiceImpl2 其中的example.MyService为接口全称,example.MyServiceImpl1,example.MyServiceImpl2为两个实现类的全称。


    官方说明: SpringFactoriesLoader loads and instantiates factories of a given type from META-INF/spring.factories files which may be present in multiple JAR files in the classpath. The file must be in {@link Properties} format, where the key is the fully qualified name of the interface or abstract class, and the value is a comma-separated list of implementation class names. For example: example.MyService=example.MyServiceImpl1,example.MyServiceImpl2 where {@code example.MyService} is the name of the interface, and {@code MyServiceImpl1} and {@code MyServiceImpl2} are two implementations.

    loadFactoryNames

    在这个方法中会遍历整个ClassLoader中所有jar包下的spring.factories文件。通过Properties解析所有接口的实现类名称。

    public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
    String factoryTypeName = factoryType.getName();
    return loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
    }

    loadFactories

    loadFactories方法首先调用loadFactoryNames方法获取待实例化的具体实现类的全称,然后调用instantiateFactory方法实例化每一个具体实现类,最终返回一个具体实现类的实例列表。

    public static <T> List<T> loadFactories(Class<T> factoryType, @Nullable ClassLoader classLoader) {
    Assert.notNull(factoryType, "'factoryType' must not be null");
    ClassLoader classLoaderToUse = classLoader;
    if (classLoaderToUse == null) {
    classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
    }
    //调用loadFactoryNames获取接口的实现类
    List<String> factoryImplementationNames = loadFactoryNames(factoryType, classLoaderToUse);
    if (logger.isTraceEnabled()) {
    logger.trace("Loaded [" + factoryType.getName() + "] names: " + factoryImplementationNames);
    }
    //遍历 factoryNames 数组,创建实现类的对象
    List<T> result = new ArrayList<>(factoryImplementationNames.size());
    for (String factoryImplementationName : factoryImplementationNames) {
    //调用instantiateFactory根据类创建实例对象
    result.add(instantiateFactory(factoryImplementationName, factoryType, classLoaderToUse));
    }
    //排序
    AnnotationAwareOrderComparator.sort(result);
    return result;
    }

    Spring Boot 默认的Factories

    Spring boot中默认使用了很多factories机制,主要包含:

  • ApplicationContextInitializer:用于在spring容器刷新之前初始化Spring ConfigurableApplicationContext的回调接口。
  • ApplicationListener:用于处理容器初始化各个阶段的事件。
  • AutoConfigurationImportListener:导入配置类的时候,获取类的详细信息(Listener that can be registered with spring.factories to receive details of imported auto-configurations.)。
  • AutoConfigurationImportFilter:用于按条件过滤导入的配置类(Filter that can be registered in spring.factories to limit the auto-configuration classes considered. This interface is designed to allow fast removal of auto-configuration classes before their bytecode is even read.)
  • EnableAutoConfiguration:指定自动加载的配置类列表(Enable auto-configuration of the Spring Application Context, attempting to guess and configure beans that you are likely to need. Auto-configuration classes are usually applied based on your classpath and what beans you have defined. For example, if you have tomcat-embedded.jar on your classpath you are likely to want a TomcatServletWebServerFactory (unless you have defined your own ServletWebServerFactory bean).
  • FailureAnalyzer:在启动时拦截异常并将其转换为易读的消息,并将其包含在FailureAnalysis中。 Spring Boot为应用程序上下文相关异常、JSR-303验证等提供了此类分析器(A FailureAnalyzer is used to analyze a failure and provide diagnostic information that can be displayed to the user.)
  • TemplateAvailabilityProvider:模版引擎配置。(Collection of TemplateAvailabilityProvider beans that can be used to check which (if any) templating engine supports a given view. Caches responses unless the spring.template.provider.cache property is set to false.)​

  • 自定义Spring Factories机制

    本节将使用一个例子来展示Spring Factories机制,案例分为两个项目spring-factories-provider和spring-factories-consume,其中spring-factories-consume可以类比于上文中的Spring Boot项目,包含Bean的接口和Bean的调用,spring-factories-provider可以类比于外部包,包含了bean的实现。项目目录结构如下:

    Spring Factories机制

    以下为各个文件的内容:

  • DemoService
  • @Service
    public class PrintDemoService {
    @PostConstruct
    public void printService(){
    List<String> serviceNames = SpringFactoriesLoader.loadFactoryNames(DemoService.class,null);
    for (String serviceName:serviceNames){
    System.out.println(serviceName);
    }

    List<DemoService> services = SpringFactoriesLoader.loadFactories(DemoService.class,null);
    for (DemoService demoService:services){
    demoService.printName();
    }
    }

  • PrintDemoService
  • public class DemoServiceImpl1 implements DemoService {
    @Override
    public void printName() {
    System.out.println("This is in demo 1.");
    }
    }

  • PrintDemoService
  • public class DemoServiceImpl1 implements DemoService {
    @Override
    public void printName() {
    System.out.println("This is in demo 1.");
    }
    }

  • DemoServiceImpl2
  • public class DemoServiceImpl2 implements DemoService {
    @Override
    public void printName() {
    System.out.println("This is in demo 2.");
    }
    }

  • FactoriesApplication
  • @SpringBootApplication
    public class FactoriesApplication {
    public static void main(String[] args) {
    SpringApplication.run(FactoriesApplication.class, args);
    }
    }

  • spring.factories
  • com.wangzemin.learning.factories.interfac.DemoService=\
    com.wangzemin.learning.factories.impl.DemoServiceImpl1,\
    com.wangzemin.learning.factories.impl.DemoServiceImpl2

    程序的运行结果如下图所示,可以看到,Factories机制已经成功发挥作用。

    在这里插入图片描述

    附录:spring boot 自带factories文件示例

    # Initializers
    org.springframework.context.ApplicationContextInitializer=\
    org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
    org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener

    # Application Listeners
    org.springframework.context.ApplicationListener=\
    org.springframework.boot.autoconfigure.BackgroundPreinitializer

    # Auto Configuration Import Listeners
    org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\
    org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener

    # Auto Configuration Import Filters
    org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\
    org.springframework.boot.autoconfigure.condition.OnBeanCondition,\
    org.springframework.boot.autoconfigure.condition.OnClassCondition,\
    org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition

    # Auto Configure
    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
    org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
    org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
    org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
    org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
    org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
    org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
    org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration,\
    org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
    org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
    org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
    org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRestClientAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.r2dbc.R2dbcRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.r2dbc.R2dbcTransactionManagerAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\
    org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration,\
    org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
    org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
    org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
    org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\
    org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\
    org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\
    org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\
    org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\
    org.springframework.boot.autoconfigure.blog.csdn.net/dieaixia5129/article/details/126081613​​

    ​​blog.csdn.net/curtinliu/article/details/111588917​​