spring boot 自动配置
来看下 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
|
@suppresswarnings ( "deprecation" )
@target (elementtype.type)
@retention (retentionpolicy.runtime)
@documented
@inherited
@autoconfigurationpackage
@import (enableautoconfigurationimportselector. class )
public @interface enableautoconfiguration {
string enabled_override_property = "spring.boot.enableautoconfiguration" ;
/**
* exclude specific auto-configuration classes such that they will never be applied.
* @return the classes to exclude
*/
class <?>[] exclude() default {};
/**
* exclude specific auto-configuration class names such that they will never be
* applied.
* @return the class names to exclude
* @since 1.3.0
*/
string[] excludename() default {};
}
|
- exclude() 可以排除一些自动配置的内容
- excludename 通过名称排除自动配置内容
再来看下, @enableautoconfiguration
是怎么处理自动配置的呢?
注意到@import(enableautoconfigurationimportselector.class)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public class enableautoconfigurationimportselector
extends autoconfigurationimportselector {
@override
protected boolean isenabled(annotationmetadata metadata) {
if (getclass().equals(enableautoconfigurationimportselector. class )) {
return getenvironment().getproperty(
enableautoconfiguration.enabled_override_property, boolean . class ,
true );
}
return true ;
}
}
}
|
再来看下 autoconfigurationimportselector
,主要是 接口的 importselector
的实现
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
|
@override
public string[] selectimports(annotationmetadata annotationmetadata) {
if (!isenabled(annotationmetadata)) {
return no_imports;
}
try {
//1、 自动配置的元数据 spring-autocomfigure-metadata.properties
// 自动配置的开启条件
autoconfigurationmetadata autoconfigurationmetadata = autoconfigurationmetadataloader
.loadmetadata( this .beanclassloader);
annotationattributes attributes = getattributes(annotationmetadata);
// 获取设置的自动配置列表 spring.factories
list<string> configurations = getcandidateconfigurations(annotationmetadata,
attributes);
configurations = removeduplicates(configurations);
configurations = sort(configurations, autoconfigurationmetadata);
// 获取要排除的自动配置列表,可以通过 注解@enableautoconfiguration 的exclude和
// 配置文件设置 spring.autoconfigure.exclude key的值
set<string> exclusions = getexclusions(annotationmetadata, attributes);
checkexcludedclasses(configurations, exclusions);
configurations.removeall(exclusions);
// 通过 spring-autocomfigure-metadata.properties conditiononclass 条件进行过滤
configurations = filter(configurations, autoconfigurationmetadata);
fireautoconfigurationimportevents(configurations, exclusions);
return configurations.toarray( new string[configurations.size()]);
}
catch (ioexception ex) {
throw new illegalstateexception(ex);
}
}
|
看下 spring.factories 文件
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
|
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,\
org.springframework.boot.autoconfigure.dao.persistenceexceptiontranslationautoconfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.cassandradataautoconfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.cassandrarepositoriesautoconfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.couchbasedataautoconfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.couchbaserepositoriesautoconfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.elasticsearchautoconfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.elasticsearchdataautoconfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.elasticsearchrepositoriesautoconfiguration,\
org.springframework.boot.autoconfigure.data.jpa.jparepositoriesautoconfiguration,\
org.springframework.boot.autoconfigure.data.ldap.ldapdataautoconfiguration,\
org.springframework.boot.autoconfigure.data.ldap.ldaprepositoriesautoconfiguration,\
org.springframework.boot.autoconfigure.data.mongo.mongodataautoconfiguration,\
org.springframework.boot.autoconfigure.data.mongo.mongorepositoriesautoconfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.neo4jdataautoconfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.neo4jrepositoriesautoconfiguration,\
org.springframework.boot.autoconfigure.data.solr.solrrepositoriesautoconfiguration,\
org.springframework.boot.autoconfigure.data.redis.redisautoconfiguration,\
org.springframework.boot.autoconfigure.data.redis.redisrepositoriesautoconfiguration,\
org.springframework.boot.autoconfigure.data.rest.repositoryrestmvcautoconfiguration,\
org.springframework.boot.autoconfigure.data.web.springdatawebautoconfiguration,\
org.springframework.boot.autoconfigure.elasticsearch.jest.jestautoconfiguration,\
org.springframework.boot.autoconfigure.freemarker.freemarkerautoconfiguration,\
org.springframework.boot.autoconfigure.gson.gsonautoconfiguration,\
org.springframework.boot.autoconfigure.h2.h2consoleautoconfiguration,\
org.springframework.boot.autoconfigure.hateoas.hypermediaautoconfiguration,\
|
再看下 spring framework中 configurationclassparser
的处理方式,会解析 @import
里的接口 importselector
返回的所有配置类,那是怎么配置的呢,如 jparepositoriesautoconfiguration
1
2
3
4
5
6
7
8
9
10
11
|
@configuration
@conditionalonbean (datasource. class )
@conditionalonclass (jparepository. class )
@conditionalonmissingbean ({ jparepositoryfactorybean. class ,
jparepositoryconfigextension. class })
@conditionalonproperty (prefix = "spring.data.jpa.repositories" , name = "enabled" , havingvalue = "true" , matchifmissing = true )
@import (jparepositoriesautoconfigureregistrar. class )
@autoconfigureafter (hibernatejpaautoconfiguration. class )
public class jparepositoriesautoconfiguration {
}
|
从上面可以看到,有很多的@conditionalon**
的注解,我们来看下 conditionevaluator
这个 条件计算器,会去计算出当前这个配置类 是否要开启,而这些 @conditionalon**
是依赖于 @conditional
这个注解,如 @conditionalonbean
最终是通过 condition 接口来作条件选择
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
|
@target ({ elementtype.type, elementtype.method })
@retention (retentionpolicy.runtime)
@documented
@conditional (onbeancondition. class )
public @interface conditionalonbean {
/**
* the class type of bean that should be checked. the condition matches when any of
* the classes specified is contained in the {@link applicationcontext}.
* @return the class types of beans to check
*/
class <?>[] value() default {};
/**
* the class type names of bean that should be checked. the condition matches when any
* of the classes specified is contained in the {@link applicationcontext}.
* @return the class type names of beans to check
*/
string[] type() default {};
/**
* the annotation type decorating a bean that should be checked. the condition matches
* when any of the annotations specified is defined on a bean in the
* {@link applicationcontext}.
* @return the class-level annotation types to check
*/
class <? extends annotation>[] annotation() default {};
/**
* the names of beans to check. the condition matches when any of the bean names
* specified is contained in the {@link applicationcontext}.
* @return the name of beans to check
*/
string[] name() default {};
/**
* strategy to decide if the application context hierarchy (parent contexts) should be
* considered.
* @return the search strategy
*/
searchstrategy search() default searchstrategy.all;
}
|
spring boot 的autoconfigure 是囊括了所有可以和spring 整合的项目,但大部分情况下,并不是所以的项目都会启用,通过 condition和@conditional 来判断条件
-
判断classpath 是否存在指定的类
@conditionalonclass
-
判断 applicationcontext 中是否存在指定的 bean
@conditionalonbean
-
配置环境中是否存在特定的配置项
@conditionalonproperty
- 配置环境中指定的配置项是否存在指定的值
禁用配置
当前 也是可以禁用某些我们不想要的默认配置,如上面加载时说到,会排除一些配置(exclude)
-
设置
@enableautoconfiguration
的exclude 配置 - 在配置文件增加 spring.autoconfigure.exclude 配置
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://www.jianshu.com/p/7261521394e7