spring.factories

spring.factories_第1张图片
image.png

spring boot中的 spring.factories 定义了一系列的ApplicationListener和ApplicationContextInitializer等其他系统所要的类。spring-boot 项目一般是这样启动:

SpringApplication application = new SpringApplication();
application.run();

new SpringApplication() 实例化SpringApplication时会进行一系统的初始化

    private void initialize(Object[] sources) {
        if (sources != null && sources.length > 0) {
            this.sources.addAll(Arrays.asList(sources));
        }
        //过程a
        this.webEnvironment = deduceWebEnvironment();
        //过程b
        setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
        setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
        this.mainApplicationClass = deduceMainApplicationClass();
    }

过程a是判断是否是web应用
过程b就是获取spring.factories文件中ApplicationListener和ApplicationContextInitializer的相应实现类,具体是通过SpringFactoriesLoader类来实现的。

private  Collection getSpringFactoriesInstances(Class type,
                                                                    Class[] parameterTypes, Object... args) {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        
        //SpringFactoriesLoader 获取type对应的实现类
        Set names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
        
        //实例化各个实现类
        List instances = createSpringFactoriesInstances(type, parameterTypes,
                classLoader, args, names);
        AnnotationAwareOrderComparator.sort(instances);
        return instances;
    }

   @SuppressWarnings("unchecked")
    private  List createSpringFactoriesInstances(Class type,
                                                       Class[] parameterTypes, ClassLoader classLoader, Object[] args,
                                                       Set names) {
        List instances = new ArrayList(names.size());
        
        for (String name : names) {
            try {
                
                Class instanceClass = ClassUtils.forName(name, classLoader);
                
                Assert.isAssignable(type, instanceClass);
                
                Constructor constructor = instanceClass.getDeclaredConstructor(parameterTypes);
                
                //实例化
                T instance = (T) BeanUtils.instantiateClass(constructor, args);
                
                instances.add(instance);
            }
            catch (Throwable ex) {
                throw new IllegalArgumentException(
                        "Cannot instantiate " + type + " : " + name, ex);
            }
        }
        return instances;
    }

具体的SpringFactoriesLoader.loadFactoryNames

public static List loadFactoryNames(Class factoryClass, ClassLoader classLoader) {
        String factoryClassName = factoryClass.getName();
        try {
            Enumeration urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
                    ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
            List result = new ArrayList();
            
            while (urls.hasMoreElements()) {
                URL url = urls.nextElement();
                Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
                String factoryClassNames = properties.getProperty(factoryClassName);
                result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));
            }
            return result;
        }
        catch (IOException ex) {
            throw new IllegalArgumentException("Unable to load [" + factoryClass.getName() +
                    "] factories from location [" + FACTORIES_RESOURCE_LOCATION + "]", ex);
        }
    }

你可能感兴趣的:(spring.factories)