首页 > 其他分享 >SpringBoot - SPI机制

SpringBoot - SPI机制

时间:2024-08-07 10:55:18浏览次数:8  
标签:SpringBoot boot springframework SPI autoconfigure diagnostics org 机制 data

SpringBoot - SPI机制

   概要

    什么是SPI呢,全称是 Service Provider Interface 。简单翻译的话,就是服务提供者接口,是一种寻找服务实现的机制。这个是针对厂商或者插件的。

    其实就是一个规范定义、或者说是实现的标准。

    一、SPI思想

    SPI的思想:系统里抽象的各个模块,往往有很多不同的实现方案,比如日志模块的方案,xml解析模块、jdbc模块的方案等。面向的对象的设计里,我们一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。一旦代码里涉及具体的实现类,就违反了可拔插的原则,如果需要替换一种实现,就需要修改代码。为了实现在模块装配的时候能不在程序里动态指明,这就需要一种服务发现机制。java SPI 就是提供这样的一个机制:为某个接口寻找服务实现的机制。

   直白一点来说就是:我定义了一个接口,但是不想固定死具体的实现类,因为那样如果要更换实现类就要改动源代码,这往往是不合适的。那么我也可以定义一个规范,在之后需要更换实现类或增加其他实现类时,遵守这个规范,我也可以动态的去发现这些实现类。


SpringBoot在启动的时候,会扫描所有jar包 resource/META-INF/spring.factories 文件,依据类的全限定名,利用反射机制将 Bean 装载进容器中。

这些监听器的实现类都是在spring.factories文件中配置好的,代码中通过getSpringFactoriesInstances方法获取,这种机制叫做SPI机制:通过本地的注册发现获取到具体的实现类,轻松可插拔。

SpringBoot默认情况下提供了两个spring.factories文件,分别是:

spring-boot-2.2.2.RELEASE.jar
spring-boot-autoconfigure-2.2.2.RELEASE.jar


二、Spring Boot中的类SPI扩展机制
在springboot的自动装配过程中,最终会加载META-INF/spring.factories文件,而加载的过程是由SpringFactoriesLoader加载的。从CLASSPATH下的每个Jar包中搜寻所有META-INF/spring.factories配置文件,然后将解析properties文件,找到指定名称的配置后返回。需要注意的是,其实这里不仅仅是会去ClassPath路径下查找,会扫描所有路径下的Jar包,只不过这个文件只会在Classpath下的jar包中。

 

  三、源码分析

  1. 入口方法 getSpringFactoriesInstances()

  根据类型获取META-INF/spring.factories文件中对应的实现类

  SpringApplication#getSpringFactoriesInstances

 1 private <T> Collection<T> getSpringFactoriesInstances(Class<T> type) {
 2     return getSpringFactoriesInstances(type, new Class<?>[]{});
 3 }
 4 
 5 private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
 6     ClassLoader classLoader = getClassLoader();
 7     // Use names and ensure unique to protect against duplicates
 8     //从META-INF/spring.factories中加载对应类型的类的自动配置类
 9     Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
10     // 加载上来后反射实例化
11     List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
12     //对实例列表进行排序
13     AnnotationAwareOrderComparator.sort(instances);
14     return instances;
15 }

  2. SpringFactoriesLoader

  我们看看它的源码(精简):

 1 public abstract class SpringFactoriesLoader {
 2 
 3     private static final Log logger = LogFactory.getLog(SpringFactoriesLoader.class);
 4 
 5     public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
 6 
 7 
 8     public static <T> List<T> loadFactories(Class<T> factoryClass, ClassLoader classLoader) {
 9 
10     }
11 
12     public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
13 
14     }
15 }

   SpringFactoriesLoader类的两个核心方法:loadFactoryNames是用来寻找spring.factories文件中的Factory名称的,loadFactories方法是用来寻找类的。

   1) loadFactoryNames 方法

   在该方法里,首先拿到ClassLoader,然后加载FactoryNames,加载类型(type)为ApplicationContextInitializer,类加载器(classLoader)为刚刚拿到的类加载器,返回值放入一个Set中,为的是确保没有重复的FactoryName,这是因为在之后加载的两个spring.factories配置文件中有两个重复的FactoryName。

   SpringFactoriesLoader#loadFactoryNames

1     public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
2         ClassLoader classLoaderToUse = classLoader;
3         if (classLoaderToUse == null) {
4             classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
5         }
6         String factoryTypeName = factoryType.getName();
7         return loadSpringFactories(classLoaderToUse).getOrDefault(factoryTypeName, Collections.emptyList());
8     }

​   可以看到,加载的配置文件在META-INF下,名称为spring.factories,该配置文件一共有两个,且配置文件中,每个段落第一行为Key,后边为value,读取时会通过key将所有的value拿出来。

​   在配置文件中我们发现,key和value都是包名加类名的字符串,因此Springboot在读取文件后,是通过反射生成的类。

   spring-boot-2.2.2.RELEASE.jar    该配置文件内容如下:
 1 # PropertySource Loaders
 2 org.springframework.boot.env.PropertySourceLoader=\
 3 org.springframework.boot.env.PropertiesPropertySourceLoader,\
 4 org.springframework.boot.env.YamlPropertySourceLoader
 5 
 6 # Run Listeners
 7 org.springframework.boot.SpringApplicationRunListener=\
 8 org.springframework.boot.context.event.EventPublishingRunListener
 9 
10 # Error Reporters
11 org.springframework.boot.SpringBootExceptionReporter=\
12 org.springframework.boot.diagnostics.FailureAnalyzers
13 
14 # Application Context Initializers
15 org.springframework.context.ApplicationContextInitializer=\
16 org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
17 org.springframework.boot.context.ContextIdApplicationContextInitializer,\
18 org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
19 org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer,\
20 org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer
21 
22 # Application Listeners
23 org.springframework.context.ApplicationListener=\
24 org.springframework.boot.ClearCachesApplicationListener,\
25 org.springframework.boot.builder.ParentContextCloserApplicationListener,\
26 org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,\
27 org.springframework.boot.context.FileEncodingApplicationListener,\
28 org.springframework.boot.context.config.AnsiOutputApplicationListener,\
29 org.springframework.boot.context.config.ConfigFileApplicationListener,\
30 org.springframework.boot.context.config.DelegatingApplicationListener,\
31 org.springframework.boot.context.logging.ClasspathLoggingApplicationListener,\
32 org.springframework.boot.context.logging.LoggingApplicationListener,\
33 org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener
34 
35 # Environment Post Processors
36 org.springframework.boot.env.EnvironmentPostProcessor=\
37 org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,\
38 org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor,\
39 org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor,\
40 org.springframework.boot.reactor.DebugAgentEnvironmentPostProcessor
41 
42 # Failure Analyzers
43 org.springframework.boot.diagnostics.FailureAnalyzer=\
44 org.springframework.boot.diagnostics.analyzer.BeanCurrentlyInCreationFailureAnalyzer,\
45 org.springframework.boot.diagnostics.analyzer.BeanDefinitionOverrideFailureAnalyzer,\
46 org.springframework.boot.diagnostics.analyzer.BeanNotOfRequiredTypeFailureAnalyzer,\
47 org.springframework.boot.diagnostics.analyzer.BindFailureAnalyzer,\
48 org.springframework.boot.diagnostics.analyzer.BindValidationFailureAnalyzer,\
49 org.springframework.boot.diagnostics.analyzer.UnboundConfigurationPropertyFailureAnalyzer,\
50 org.springframework.boot.diagnostics.analyzer.ConnectorStartFailureAnalyzer,\
51 org.springframework.boot.diagnostics.analyzer.NoSuchMethodFailureAnalyzer,\
52 org.springframework.boot.diagnostics.analyzer.NoUniqueBeanDefinitionFailureAnalyzer,\
53 org.springframework.boot.diagnostics.analyzer.PortInUseFailureAnalyzer,\
54 org.springframework.boot.diagnostics.analyzer.ValidationExceptionFailureAnalyzer,\
55 org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyNameFailureAnalyzer,\
56 org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyValueFailureAnalyzer
57 
58 # FailureAnalysisReporters
59 org.springframework.boot.diagnostics.FailureAnalysisReporter=\
60 org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter
View Code    spring-boot-autoconfigure-2.2.2.RELEASE.jar    该配置文件内容如下:
  1 # Initializers
  2 org.springframework.context.ApplicationContextInitializer=\
  3 org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
  4 org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener
  5 
  6 # Application Listeners
  7 org.springframework.context.ApplicationListener=\
  8 org.springframework.boot.autoconfigure.BackgroundPreinitializer
  9 
 10 # Auto Configuration Import Listeners
 11 org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\
 12 org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener
 13 
 14 # Auto Configuration Import Filters
 15 org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\
 16 org.springframework.boot.autoconfigure.condition.OnBeanCondition,\
 17 org.springframework.boot.autoconfigure.condition.OnClassCondition,\
 18 org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition
 19 
 20 # Auto Configure
 21 org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
 22 org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
 23 org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
 24 org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
 25 org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
 26 org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
 27 org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
 28 org.springframework.boot.autoconfigure.cloud.CloudServiceConnectorsAutoConfiguration,\
 29 org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
 30 org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
 31 org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
 32 org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
 33 org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
 34 org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
 35 org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration,\
 36 org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration,\
 37 org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
 38 org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
 39 org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration,\
 40 org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration,\
 41 org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
 42 org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,\
 43 org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
 44 org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
 45 org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration,\
 46 org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveRestClientAutoConfiguration,\
 47 org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration,\
 48 org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
 49 org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
 50 org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
 51 org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration,\
 52 org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration,\
 53 org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
 54 org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\
 55 org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
 56 org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
 57 org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
 58 org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration,\
 59 org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\
 60 org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\
 61 org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\
 62 org.springframework.boot.autoconfigure.elasticsearch.jest.JestAutoConfiguration,\
 63 org.springframework.boot.autoconfigure.elasticsearch.rest.RestClientAutoConfiguration,\
 64 org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
 65 org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
 66 org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\
 67 org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\
 68 org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\
 69 org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\
 70 org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\
 71 org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration,\
 72 org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration,\
 73 org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration,\
 74 org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,\
 75 org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\
 76 org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\
 77 org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
 78 org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
 79 org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,\
 80 org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,\
 81 org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
 82 org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\
 83 org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\
 84 org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,\
 85 org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,\
 86 org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,\
 87 org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
 88 org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\
 89 org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
 90 org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration,\
 91 org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\
 92 org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,\
 93 org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,\
 94 org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\
 95 org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\
 96 org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,\
 97 org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\
 98 org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
 99 org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration,\
100 org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
101 org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
102 org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,\
103 org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration,\
104 org.springframework.boot.autoconfigure.rsocket.RSocketRequesterAutoConfiguration,\
105 org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration,\
106 org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration,\
107 org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\
108 org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration,\
109 org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration,\
110 org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration,\
111 org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration,\
112 org.springframework.boot.autoconfigure.security.rsocket.RSocketSecurityAutoConfiguration,\
113 org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyAutoConfiguration,\
114 org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\
115 org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\
116 org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration,\
117 org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration,\
118 org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration,\
119 org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration,\
120 org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\
121 org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration,\
122 org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration,\
123 org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\
124 org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\
125 org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,\
126 org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,\
127 org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration,\
128 org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration,\
129 org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration,\
130 org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration,\
131 org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration,\
132 org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration,\
133 org.springframework.boot.autoconfigure.web.reactive.function.client.ClientHttpConnectorAutoConfiguration,\
134 org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration,\
135 org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\
136 org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\
137 org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration,\
138 org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\
139 org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration,\
140 org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
141 org.springframework.boot.autoconfigure.websocket.reactive.WebSocketReactiveAutoConfiguration,\
142 org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration,\
143 org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration,\
144 org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration,\
145 org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration
146 
147 # Failure analyzers
148 org.springframework.boot.diagnostics.FailureAnalyzer=\
149 org.springframework.boot.autoconfigure.diagnostics.analyzer.NoSuchBeanDefinitionFailureAnalyzer,\
150 org.springframework.boot.autoconfigure.flyway.FlywayMigrationScriptMissingFailureAnalyzer,\
151 org.springframework.boot.autoconfigure.jdbc.DataSourceBeanCreationFailureAnalyzer,\
152 org.springframework.boot.autoconfigure.jdbc.HikariDriverConfigurationFailureAnalyzer,\
153 org.springframework.boot.autoconfigure.session.NonUniqueSessionRepositoryFailureAnalyzer
154 
155 # Template availability providers
156 org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=\
157 org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider,\
158 org.springframework.boot.autoconfigure.mustache.MustacheTemplateAvailabilityProvider,\
159 org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider,\
160 org.springframework.boot.autoconfigure.thymeleaf.ThymeleafTemplateAvailabilityProvider,\
161 org.springframework.boot.autoconfigure.web.servlet.JspTemplateAvailabilityProvider
View Code

   2) loadFactories 方法

   SpringFactoriesLoader#loadFactories

 1 private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
 2     //到缓存中读取
 3     MultiValueMap<String, String> result = cache.get(classLoader);
 4     //如果存在则直接返回
 5     if (result != null) {
 6         return result;
 7     }
 8 
 9     try {
10         //获取所以jar包META-INF/spring.factories对应的URL
11         Enumeration<URL> urls = (classLoader != null ?
12                                  classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
13                                  ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
14         result = new LinkedMultiValueMap<>();
15         //遍历数据
16         while (urls.hasMoreElements()) {
17             URL url = urls.nextElement();
18             //获取到资源数据
19             UrlResource resource = new UrlResource(url);
20             //加载配置文件
21             Properties properties = PropertiesLoaderUtils.loadProperties(resource);
22             //遍历解析配置文件
23             for (Map.Entry<?, ?> entry : properties.entrySet()) {
24                 String factoryTypeName = ((String) entry.getKey()).trim();
25                 for (String factoryImplementationName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {
26                     //将spring.factories配置文件数据放进结果集
27                     result.add(factoryTypeName, factoryImplementationName.trim());
28                 }
29             }
30         }
31         //加入缓存
32         cache.put(classLoader, result);
33         //返回结果
34         return result;
35     }
36     catch (IOException ex) {
37         throw new IllegalArgumentException("Unable to load factories from location [" +
38                                            FACTORIES_RESOURCE_LOCATION + "]", ex);
39     }
40 }

   读取完spring.factories后,把读取到的内容(13个key)存储到枚举类中,然后遍历枚举类,将里边内容都add到一个map(result)里边去,最后把classloader以及遍历的结果都放入cache中,提高加载资源的效率。

   3. createSpringFactoriesInstances

  目前已经取出所有的配置,但还没有进行初始化,该方法是实例化对象的

  SpringApplication#createSpringFactoriesInstances

 1 private <T> List<T> createSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes,
 2                                                    ClassLoader classLoader, Object[] args, Set<String> names) {
 3     List<T> instances = new ArrayList<>(names.size());
 4     for (String name : names) {
 5         try {
 6             Class<?> instanceClass = ClassUtils.forName(name, classLoader);
 7             Assert.isAssignable(type, instanceClass);
 8             //获取构造方法
 9             Constructor<?> constructor = instanceClass.getDeclaredConstructor(parameterTypes);
10             //实例化对象
11             T instance = (T) BeanUtils.instantiateClass(constructor, args);
12             //加入instances实例列表
13             instances.add(instance);
14         } catch (Throwable ex) {
15             throw new IllegalArgumentException("Cannot instantiate " + type + " : " + name, ex);
16         }
17     }
18     return instances;
19 }

 

 

 

  参考链接:

  https://www.baiyp.ren/SpringBoot%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90-SPI%E6%9C%BA%E5%88%B6.html

标签:SpringBoot,boot,springframework,SPI,autoconfigure,diagnostics,org,机制,data
From: https://www.cnblogs.com/hld123/p/18346628

相关文章

  • 免费分享一套SpringBoot+Vue新闻发布推荐系统【论文+源码+SQL脚本】,帅呆了~~
    大家好,我是java1234_小锋老师,看到一个不错的SpringBoot+Vue图书(图书借阅)管理系统,分享下哈。项目视频演示【免费】SpringBoot+Vue新闻发布推荐系统Java毕业设计_哔哩哔哩_bilibili项目介绍随着信息互联网购物的飞速发展,国内放开了自媒体的政策,一般企业都开始开发属于自......
  • 25届计算机毕业设计选题-基于springboot的二手图书交易系统
    博主介绍:✌十余年IT大项目实战经验、在某机构培训学员上千名、专注于本行业领域✌技术范围:Java实战项目、Python实战项目、微信小程序/安卓实战项目、爬虫+大数据实战项目、Nodejs实战项目、PHP实战项目、.NET实战项目、Golang实战项目。主要内容:系统功能设计、开题报告......
  • IDEA创建SpringBoot项目
    SpringBoot项目创建SpringBoot项目步骤:第一步:新建一个项目第二步:选择SpringBoot项目,按照图上的步骤选择并输入对应内容,之后点击next进行下一步。注:第二小步可改用阿里云:https://start.aliyun.com第三步:勾选SpringWeb,并点击finish完成项目的创建SpringBoot......
  • SQL Server数据库的清洁工:垃圾回收机制解析
    SQLServer数据库的清洁工:垃圾回收机制解析在SQLServer的复杂而精密的数据库管理系统中,垃圾回收机制扮演着至关重要的角色。它负责清理不再需要的数据,释放空间供新数据使用。本文将深入探讨SQLServer中数据库垃圾回收机制的工作原理,并提供代码示例,帮助你更好地理解这一自......
  • 编程深水区之并发②:JS的单线程事件循环机制
    如果某天有人问你,Node.js是单线程还是多线程,你如何回答?一、单线程并发原理我们以处理Web请求为例,来看看Node在处理并发请求时,究竟发生了什么。Node启动Web服务器后,创建主线程(只有一个)。当有一个阻塞请求过来时,主线程不会发生阻塞,而是继续处理其它代码或请求。如果阻塞......
  • 多头自注意力机制计算举例
    多头自注意力机制计算示例多头自注意力机制计算示例1.输入序列和权重矩阵假设输入序列X如下:X[1,0,1,0][0,1,0,1][1,1,1,1]我们有两个头,分别对应的权重矩阵如下:头1WQ(1)WK(1)WV(1)[1,0][1,0][1,0][0,1][0,1][0,1][1,0][1,......
  • 对于springboot无法连接redis解决方案
    对于springboot无法连接redis解决方案一、测试是否能在本地应用上访问到你的redis(如果是部署在linux上的话)1.开启telnet功能2.开始测试端口是否能访问到(适用于所有,包括MQ)3.开放6379端口4.看spring的配置文件注意redis的缩进位置5.pom依赖一、测试是否能在本地......
  • Springboot计算机毕业设计电影推荐网站0unwo
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表用户,电影分类,电影信息,通知公告,电影资讯开题报告内容一、研究背景与意义随着互联网技术的飞速发展,在线娱乐已成为人们日常生活中不可或缺的一部分。电影作为......
  • Springboot计算机毕业设计电商订单管理系统(程序+源码+数据库)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表用户,商品分类,商家,商品信息开题报告内容摘要本文旨在设计并实现一个高效、易用的电商订单管理系统,以满足现代电商企业对订单处理、库存控制、物流跟踪及财务......
  • Springboot计算机毕业设计电脑商城购物系统(数据库、调试部署、开发环境)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表用户,商品分类,商品品牌,商品信息开题报告内容1.选题背景及意义1.1选题背景随着计算机和网络的普及,电子商务已经成为现代社会不可或缺的一部分。特别是在21......