好得很程序员自学网

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

SpringBoot自动配置的实现原理

一、运行原理

spring boot的运行是由注解@enableautoconfiguration提供的。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

@target ({elementtype.type})

@retention (retentionpolicy.runtime)

@documented

@inherited

@autoconfigurationpackage

@import ({enableautoconfigurationimportselector. class })

public @interface enableautoconfiguration {

   string enabled_override_property = "spring.boot.enableautoconfiguration" ;

 

   class <?>[] exclude() default {};

 

   string[] excludename() default {};

}

这里的关键功能是@import注解。enableautoconfigurationimportselector使用springfactoriesloader.loadfactorynames方法来扫描具有meat-inf/spring.factories文件的jar包(1.5版本以前使用enableautoconfigurationimportselector类,1.5以后这个类废弃了使用的是autoconfigurationimportselector类),下面是spring-boot-autoconfigure-1.5.4.release.jar下的meat-inf中的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

# initializers

org.springframework.context.applicationcontextinitializer=\

org.springframework.boot.autoconfigure.sharedmetadatareaderfactorycontextinitializer,\

org.springframework.boot.autoconfigure.logging.autoconfigurationreportlogginginitializer

 

# application listeners

org.springframework.context.applicationlistener=\

org.springframework.boot.autoconfigure.backgroundpreinitializer

 

# auto configuration import listeners

org.springframework.boot.autoconfigure.autoconfigurationimportlistener=\

org.springframework.boot.autoconfigure.condition.conditionevaluationreportautoconfigurationimportlistener

 

# auto configuration import filters

org.springframework.boot.autoconfigure.autoconfigurationimportfilter=\

org.springframework.boot.autoconfigure.condition.onclasscondition

 

# auto configure

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,\

里面的类都是自动配置类,springboot会根据这些自动配置类去自动配置环境。

下面我们就自动动手写一个starter。

二、自定义starter

首先先介绍几个条件注解。

@conditionalonbean:当容器里有指定的bean为true @conditionalonclass:当类路径下有指定的类为true @conditionalonmissingbean:当容器里没有指定的bean为true @conditionalonproperty:指定的数据是否有指定的值 ...

了解了条件注解后,我们开始自定义starter。

1、在自定义starter之前先要在maven中填写依赖。

?

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

<?xml version= "1.0" encoding= "utf-8" ?>

<project xmlns= "http://maven.apache.org/pom/4.0.0" xmlns:xsi= "http://www.w3.org/2001/xmlschema-instance"

   xsi:schemalocation= "http://maven.apache.org/pom/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" >

   <modelversion> 4.0 . 0 </modelversion>

 

   <groupid>cn.miaolovezhen</groupid>

   <artifactid>spring-boot-starter-test</artifactid>

   <version> 0.0 . 1 -snapshot</version>

   <packaging>jar</packaging>

 

   <name>spring-boot-starter-test</name>

   <description>demo project for spring boot</description>

 

   <parent>

    <groupid>org.springframework.boot</groupid>

    <artifactid>spring-boot-starter-parent</artifactid>

    <version> 1.5 . 6 .release</version>

    <relativepath/> <!-- lookup parent from repository -->

   </parent>

 

   <properties>

    <project.build.sourceencoding>utf- 8 </project.build.sourceencoding>

    <project.reporting.outputencoding>utf- 8 </project.reporting.outputencoding>

    <java.version> 1.8 </java.version>

   </properties>

 

   <dependencies>

    <dependency>

      <groupid>org.springframework.boot</groupid>

      <artifactid>spring-boot-autoconfigure</artifactid>

      <version> 1.5 . 4 .release</version>

    </dependency>

   </dependencies>

 

</project>

2、完成testproperties类,这个类定义了默认的属性值,如该类中,只有一个属性值msg,默认为world。@configurationproperties注解会定义一个匹配,如果想修改属性值,可以在application.properties中使用[匹配.属性=修改的值]进行修改。如test.msg = tan

?

1

2

3

4

5

6

7

8

9

10

11

12

13

@configurationproperties (prefix = "test" )

public class testproperties {

   private static final string msg = "springboot" ;

   private string msg = msg;

 

   public string getmsg() {

     return msg;

   }

 

   public void setmsg(string msg) {

     this .msg = msg;

   }

}

3、完成服务类。服务类是指主要的功能类,如果没有springboot,这些服务类在spring中都是需要自己去配置生成的。如springmvc中的dispatcherservlet、mybatis的datasource等。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

public class testservice {

   private string msg;

 

   public string sayhello(){

     return "hello " + msg;

   }

 

   public string getmsg() {

     return msg;

   }

 

   public void setmsg(string msg) {

     this .msg = msg;

   }

}

4、完成自动配置类。自动配置类主要作用是springboot的配置核心,它会写在meat-inf/spring.factories中,告知springboot在启动时去读取该类并根据该类的规则进行配置。

@enableconfigurationproperties注解根据testproperties类开启属性注入,允许在application.properties修改里面的属性值。 @conditiononclass会检测是否存在testservice类 @conditiononproperty类会查看是否开启该自动配置。默认开启(true)。 @conditiononmissingbean会检测容器中是否有testservice类的对象,如果没有则生成一个。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

@configuration

@enableconfigurationproperties (testproperties. class )

@conditionalonclass (testservice. class )

@conditionalonproperty (prefix = "test" , value = "enabled" , matchifmissing = true )

public class testserviceautoconfiguration {

   @autowired

   testproperties testproperties;

 

   @bean

   @conditionalonmissingbean (testservice. class )

   public testservice testservice(){

     testservice testservice = new testservice();

     testservice.setmsg(testproperties.getmsg());

     return testservice;

   }

}

5、最后一步,不要忘记在在meat-inf文件夹中创建spring.factories文件。内容很简单,告诉springboot去读取testserviceautoconfiguration类。

?

1

2

org.springframework.boot.autoconfigure.enableautoconfiguration=\

cn.miaolovezhen.testserviceautoconfiguration

好啦,搞定!下面可以使用maven install命令把starter存到本地,其他springboot项目需要使用这个starter,直接导入就可以啦。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

原文链接:https://segmentfault.com/a/1190000017780558

查看更多关于SpringBoot自动配置的实现原理的详细内容...

  阅读:10次