Spring 自 3.2 引入 spring.factories SPI 后并没有真正的利用起来,使用的地方比较少,然而真正把 spring.factories 发扬光大的是在 Spring Boot 中

那在springboot中,spring.factories什么时候被加载的呢,里面的类又是什么时候被实例化的呢?
从一个普通的springboot项目的main方法进去

run方法启动

 实例化SpringApplication

在实例化的过程中,会对一些内容进行初始化,其中就包括spring.factories的内容。


就是这里,一个读取里面的类全限定性类名,然后进行实例化。
 
加载

初始化
循环遍历,逐一初始化,用的是java的反射机制

反射, forName
public static Class<?> forName(String name,  ClassLoader classLoader) throws ClassNotFoundException, LinkageError {
        Assert.notNull(name, "Name must not be null");
        Class<?> clazz = resolvePrimitiveClassName(name);
        if (clazz == null) {
            clazz = (Class)commonClassCache.get(name);
        }
        if (clazz != null) {
            return clazz;
        } else {
            Class elementClass;
            String elementName;
            if (name.endsWith("[]")) {
                elementName = name.substring(0, name.length() - "[]".length());
                elementClass = forName(elementName, classLoader);
                return Array.newInstance(elementClass, 0).getClass();
            } else if (name.startsWith("[L") && name.endsWith(";")) {
                elementName = name.substring("[L".length(), name.length() - 1);
                elementClass = forName(elementName, classLoader);
                return Array.newInstance(elementClass, 0).getClass();
            } else if (name.startsWith("[")) {
                elementName = name.substring("[".length());
                elementClass = forName(elementName, classLoader);
                return Array.newInstance(elementClass, 0).getClass();
            } else {
                ClassLoader clToUse = classLoader;
                if (classLoader == null) {
                    clToUse = getDefaultClassLoader();
                }
                try {
                    return Class.forName(name, false, clToUse);
                } catch (ClassNotFoundException var9) {
                    int lastDotIndex = name.lastIndexOf(46);
                    if (lastDotIndex != -1) {
                        String nestedClassName = name.substring(0, lastDotIndex) + '$' + name.substring(lastDotIndex + 1);
                        try {
                            return Class.forName(nestedClassName, false, clToUse);
                        } catch (ClassNotFoundException var8) {
                        }
                    }
                    throw var9;
                }
            }
        }
    }
                










