Spring-boot自动配置原理

释放双眼,带上耳机,听听看~!

首先利用Spring Initializr方式创建springboot项目,查看springboot主配置类:


1
2
3
4
1@SpringBootApplication
2public class SpringBootAutoconfigurationYuanliApplication {
3
4

点击进入SpringBootApplication注解


1
2
3
4
5
1@SpringBootConfiguration
2@EnableAutoConfiguration
3public @interface SpringBootApplication {}
4
5

其中的@SpringBootConfiguration标注在某个类上,表示这是一个Spring Boot的配置类, 点击注解查看源码


1
2
3
4
5
1@Configuration
2public @interface SpringBootConfiguration {
3}
4
5

发现其依赖注解@Configuration
@Configuration配置在该注解类上来标注这个注解是一个配置类。
返回到@EnableAutoConfiguration,点击进入其源码


1
2
3
4
5
1@AutoConfigurationPackage
2@Import({AutoConfigurationImportSelector.class})
3public @interface EnableAutoConfiguration {
4
5

存在着@AutoConfigurationPackage和一个底层注解@Import,先讨论@AutoConfigurationPackage,点击进入其源码


1
2
3
4
5
1@Import({Registrar.class})
2public @interface AutoConfigurationPackage {
3}
4
5

同样使用了@Import,并且参数为Registrar.class再次点击Registrar.class发现如下方法


1
2
3
4
5
1public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
2   AutoConfigurationPackages.register(registry, (new AutoConfigurationPackages.PackageImport(metadata)).getPackageName());
3}
4
5

以DeBug形式运行分析new AutoConfigurationPackages.PackageImport(metadata).getPackageName()
得到结果是扫描主配置类所在包的所有组件Spring-boot自动配置原理
Spring-boot自动配置原理
回到@Import({AutoConfigurationImportSelector.class})
点击进入AutoConfigurationImportSelector.class自动配置选择器的源码中,发现其中有两个方法:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
1public String[] selectImports(AnnotationMetadata annotationMetadata) {
2        if (!this.isEnabled(annotationMetadata)) {
3            return NO_IMPORTS;
4        } else {
5            AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
6            AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);
7            return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
8        }
9    }
10
11    protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata, AnnotationMetadata annotationMetadata) {
12        if (!this.isEnabled(annotationMetadata)) {
13            return EMPTY_ENTRY;
14        } else {
15            AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
16            List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
17            configurations = this.removeDuplicates(configurations);
18            Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
19            this.checkExcludedClasses(configurations, exclusions);
20            configurations.removeAll(exclusions);
21            configurations = this.filter(configurations, autoConfigurationMetadata);
22            this.fireAutoConfigurationImportEvents(configurations, exclusions);
23            return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
24        }
25    }
26
27

第一个方法是导入注解元信息选择器,方法中调用了类中的getAutoConfigurationEntry()方法,也就是第二个方法,第二个方法中返回的信息主要有configurations,和exclusions,在此主要分析List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);点击getCandidateConfigurations方法:


1
2
3
4
5
6
7
1protected List&lt;String&gt; getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
2        List&lt;String&gt; configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
3        Assert.notEmpty(configurations, &quot;No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.&quot;);
4        return configurations;
5    }
6
7

继续点击loadFactoryNames方法:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
1public static List&lt;String&gt; loadFactoryNames(Class&lt;?&gt; factoryClass, @Nullable ClassLoader classLoader) {
2        String factoryClassName = factoryClass.getName();
3        return (List)loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
4    }
5
6private static Map&lt;String, List&lt;String&gt;&gt; loadSpringFactories(@Nullable ClassLoader classLoader) {
7    MultiValueMap&lt;String, String&gt; result = (MultiValueMap)cache.get(classLoader);
8    if (result != null) {
9        return result;
10    } else {
11        try {
12            Enumeration&lt;URL&gt; urls = classLoader != null ? classLoader.getResources(&quot;META-INF/spring.factories&quot;) : ClassLoader.getSystemResources(&quot;META-INF/spring.factories&quot;);
13            LinkedMultiValueMap result = new LinkedMultiValueMap();
14
15            while(urls.hasMoreElements()) {
16                URL url = (URL)urls.nextElement();
17                UrlResource resource = new UrlResource(url);
18                Properties properties = PropertiesLoaderUtils.loadProperties(resource);
19                Iterator var6 = properties.entrySet().iterator();
20
21                while(var6.hasNext()) {
22                    Entry&lt;?, ?&gt; entry = (Entry)var6.next();
23                    String factoryClassName = ((String)entry.getKey()).trim();
24                    String[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
25                    int var10 = var9.length;
26
27                    for(int var11 = 0; var11 &lt; var10; ++var11) {
28                        String factoryName = var9[var11];
29                        result.add(factoryClassName, factoryName.trim());
30                    }
31                }
32            }
33
34            cache.put(classLoader, result);
35            return result;
36        } catch (IOException var13) {
37            throw new IllegalArgumentException(&quot;Unable to load factories from location [META-INF/spring.factories]&quot;, var13);
38        }
39    }
40}
41
42

loadFactoryNames方法返回loadSpringFactories方法的结果,
其中先获取ClassLoader.getSystemResources(“META-INF/spring.factories”)文件中的url,即是扫描jar包类路径下的META-INF/spring.factories文件中的内容,接着,我们查看扫描的是哪一个jar包下的文件,点击 getCandidateConfigurations中的this.getSpringFactoriesLoaderFactoryClass(),


1
2
3
4
5
1 protected Class&lt;?&gt; getSpringFactoriesLoaderFactoryClass() {
2        return EnableAutoConfiguration.class;
3    }
4
5

EnableAutoConfiguration.class是允许自动配置类
Spring-boot自动配置原理
文件内容:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
1# Auto Configure
2org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
3org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
4org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
5org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
6org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
7org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
8org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
9org.springframework.boot.autoconfigure.cloud.CloudServiceConnectorsAutoConfiguration,\
10org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
11org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
12org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
13org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
14org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
15org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
16org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration,\
17org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration,\
18org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
19org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
20org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration,\
21org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration,\
22org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
23org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,\
24org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
25org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
26org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration,\
27org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
28org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
29org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
30org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration,\
31org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration,\
32org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
33org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\
34org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
35org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
36org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
37org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration,\
38org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\
39org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\
40org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\
41org.springframework.boot.autoconfigure.elasticsearch.jest.JestAutoConfiguration,\
42org.springframework.boot.autoconfigure.elasticsearch.rest.RestClientAutoConfiguration,\
43org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
44org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
45org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\
46org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\
47org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\
48org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\
49org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\
50org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration,\
51org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration,\
52org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration,\
53org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,\
54org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\
55org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\
56org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
57org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
58org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,\
59org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,\
60org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
61org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\
62org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\
63org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,\
64org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,\
65org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,\
66org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
67org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\
68org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
69org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration,\
70org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\
71org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,\
72org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,\
73org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\
74org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\
75org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,\
76org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\
77org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
78org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration,\
79org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
80org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
81org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,\
82org.springframework.boot.autoconfigure.reactor.core.ReactorCoreAutoConfiguration,\
83org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\
84org.springframework.boot.autoconfigure.security.servlet.SecurityRequestMatcherProviderAutoConfiguration,\
85org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration,\
86org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration,\
87org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration,\
88org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration,\
89org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\
90org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\
91org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration,\
92org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration,\
93org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration,\
94org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration,\
95org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\
96org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration,\
97org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration,\
98org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\
99org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\
100org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,\
101org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,\
102org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration,\
103org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration,\
104org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration,\
105org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration,\
106org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration,\
107org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration,\
108org.springframework.boot.autoconfigure.web.reactive.function.client.ClientHttpConnectorAutoConfiguration,\
109org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration,\
110org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\
111org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\
112org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration,\
113org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\
114org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration,\
115org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
116org.springframework.boot.autoconfigure.websocket.reactive.WebSocketReactiveAutoConfiguration,\
117org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration,\
118org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration,\
119org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration,\
120org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration
121
122
123

将遍历结果包装成properties对象。
每一个这样的 xxxAutoConfiguration类都是容器中的一个组件,都加入到容器中;用他们来做自动配置。
HttpEncodingAutoConfiguration(Http编码自动配置) 为例解释自动配置原理


1
2
3
4
5
6
7
8
9
10
11
12
13
1@Configuration  //表示这是一个配置类,以前编写的配置文件一样,也可以给容器中添加组件
2@EnableConfigurationProperties({HttpProperties.class}) //启动指定类的ConfigurationProperties功能;
3//将自己编写的application.properties配置文件中对应的值和HttpEncodingProperties类绑定起来;并把HttpEncodingProperties加入到ioc容器中
4@ConditionalOnWebApplication(type = Type.SERVLET)
5@ConditionalOnClass({CharacterEncodingFilter.class})
6@ConditionalOnProperty(
7    prefix = &quot;spring.http.encoding&quot;,
8    value = {&quot;enabled&quot;},
9    matchIfMissing = true
10)
11public class HttpEncodingAutoConfiguration {
12
13

点击HttpProperties.class进入此类发现此类中有注解@ConfigurationProperties(prefix = “spring.http”)也就指明了此类配置的编写方式都是以spring.http为前缀,后面属性都是该类中的属性。

给TA打赏
共{{data.count}}人
人已打赏
安全技术

C++调用Python

2022-1-11 12:36:11

安全资讯

华为干部都不怕领导?任正非肯定轮值机制:不能一朝天子一朝臣

2020-5-15 11:36:11

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索