首页 > 编程 > Java > 正文

SpringBoot自动配置的实现原理

2019-11-26 09:22:36
字体:
来源:转载
供稿:网友

一、运行原理

Spring Boot的运行是由注解@EnableAutoConfiguration提供的。

@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文件的部分内容。

# Initializersorg.springframework.context.ApplicationContextInitializer=/org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,/org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer # Application Listenersorg.springframework.context.ApplicationListener=/org.springframework.boot.autoconfigure.BackgroundPreinitializer # Auto Configuration Import Listenersorg.springframework.boot.autoconfigure.AutoConfigurationImportListener=/org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener # Auto Configuration Import Filtersorg.springframework.boot.autoconfigure.AutoConfigurationImportFilter=/org.springframework.boot.autoconfigure.condition.OnClassCondition # Auto Configureorg.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中填写依赖。

<?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

@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等。

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类的对象,如果没有则生成一个。
@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类。

org.springframework.boot.autoconfigure.EnableAutoConfiguration=/cn.miaolovezhen.TestServiceAutoConfiguration

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

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

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表