SPRINGBOOT启动原理(基于2.x版本)-SpringFactoriesLoader

Posted 盖丽男

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SPRINGBOOT启动原理(基于2.x版本)-SpringFactoriesLoader相关的知识,希望对你有一定的参考价值。

目录

版本

版本:2.5.5
上一篇:SPRINGBOOT启动原理(基于2.x版本)(一)

SpringFactoriesLoader

引入

从上一篇可以看到,代码中频繁地使用到了SpringFactoriesLoader这个类,大致能看出来是为了拿类的,今天我们详细的研究一下。

介绍

看一下官网的介绍:

General purpose factory loading mechanism for internal use within the framework.
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 spring.factories file must be in 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 example.MyService is the name of the interface, and MyServiceImpl1 and MyServiceImpl2 are two implementations.

翻译一下:
用于框架内部使用的通用工厂加载机制。

SpringFactoriesLoader从“META-INF/spring.factories”文件加载和实例化给定类型的工厂,这些文件可能存在于类路径中的多个 JAR 文件中。该spring.factories 文件必须采用Properties格式,其中key是接口或抽象类的完全限定名称,value为相应的实现类,当存在多个实现类时,用“,”进行分割。
然后举了个例子

代码

最常用到的方法就是

SpringFactoriesLoader.loadFactories

我们自己写一个来试一试,先看下目录结构:

具体代码:

public interface Fruit 
    void Color();


public class Banana implements Fruit
    public Banana()
        System.out.println("A Banana");
    

    @Override
    public void Color() 
        System.out.println("yello");
    


public class Orange implements Fruit

    public Orange()
        System.out.println("An Orange");
    

    @Override
    public void Color() 
        System.out.println("orange");
    


spring.factories

com.example.mavendemo.loadertest.Fruit=com.example.mavendemo.loadertest.Banana,com.example.mavendemo.loadertest.Orange

测试方法:

@SpringBootTest
class FruitTest 

    @Test
    public void testLoadFactoryNames() 
        //获取所有META-INF/spring.factories中的value值
        List<String> applicationContextInitializers = SpringFactoriesLoader.loadFactoryNames(Fruit.class, ClassUtils.getDefaultClassLoader());
        for (String applicationContextInitializer : applicationContextInitializers) 
            System.out.println(applicationContextInitializer);
        
    

    @Test
    public void testLoadFactories() 
        //实例化所有在META-INF/spring.factories配置的且实现BeanInfoFactory接口的类
        List<Fruit> fruitFactories = SpringFactoriesLoader.loadFactories(Fruit.class, ClassUtils.getDefaultClassLoader());

        for (Fruit fruit : fruitFactories) 
            System.out.println(fruitFactories);
        
    

参考

Spring SpringFactoriesLoader

以上是关于SPRINGBOOT启动原理(基于2.x版本)-SpringFactoriesLoader的主要内容,如果未能解决你的问题,请参考以下文章

SPRINGBOOT启动原理(基于2.x版本)- SpringApplication里有啥

SpringBoot运行原理

关于SpringBoot 1.x和2.x版本差别

SpringBoot 2.x版本整合redis集群

springboot启动为啥控制台要输出一个图案?

SpringBoot启动原理分析