在之前的一些文章中,我们提到过从spring.factories中找出key为XXX的类。比如@EnableAutoConfiguration注解对应的EnableAutoConfigurationImportSelector中的selectImport方法会在spring.factories文件中找出key为EnableAutoConfiguration对应的值。这些类都是自动化配置类:
// 这个spring.factories文件在spring-boot-autoconfigure模块的 META-INF/spring.factories中
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.cloud.CloudAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
......
代码的实现,EnableAutoConfigurationImportSelector的selectImport方法:
1 |
|
Spring Framework内部使用一种工厂加载机制(Factory Loading Mechanism)。这种机制使用SpringFactoriesLoader完成,SpringFactoriesLoader使用loadFactories方法加载并实例化从META-INF目录里的spring.factories文件出来的工厂,这些spring.factories文件都是从classpath里的jar包里找出来的。
spring.factories文件是以Java的Properties格式存在,key是接口或抽象类的全名、value是以逗号 “ , “ 分隔的实现类,比如:
example.MyService=example.MyServiceImpl1,example.MyServiceImpl2
其中example.MyService是接口的全名,example.MyServiceImpl1和example.MyServiceImpl2是这个接口的两种实现。
可通过SpringFactoriesLoader完成:
1 | List<String> classes = SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class, this.getClass().getClassLoader()); |
总结:
工厂加载机制是Spring内部提供的一个约定俗成的加载方式。只需要在模块的META-INF目录下定义Properties格式的spring.factories文件,这个Properties格式的文件中的key是接口或抽象类的全名,value是以逗号 “ , “ 分隔的实现类。
SpringBoot中的autoconfigure模块中的spring.factories就存在于META-INF目录下:
├── META-INF
│ ├── MANIFEST.MF
│ ├── additional-spring-configuration-metadata.json
│ ├── maven
│ │ └── org.springframework.boot
│ │ └── spring-boot-autoconfigure
│ │ ├── pom.properties
│ │ └── pom.xml
│ ├── spring-configuration-metadata.json
│ └── spring.factories
├── org
│ └── springframework
│ └── boot
│ └── autoconfigure
│ ├── AbstractDependsOnBeanFactoryPostProcessor.class
....
而且也定义了一些配置,比如自动化配置信息:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=...
应用初始化器:
org.springframework.context.ApplicationContextInitializer=...
应用监听器:
org.springframework.context.ApplicationListener=...
模板可用提供器:
org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=...
等等。
我们只需要遵守这个机制并在对应的文件中写出需要加载的接口和实例即可,或者自己使用SpringFactoriesLoader实现加载。