好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Spring Boot 自动配置的实现

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

查看更多关于Spring Boot 自动配置的实现的详细内容...

  阅读:35次