SpringBoot自动配置的实现原理

 更新时间:2019年01月07日 09:05:16   作者:LNMPR源码研究  
这篇文章主要介绍了详解SpringBoot自动配置原理,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

一、运行原理

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

# 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中填写依赖。

<?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,直接导入就可以啦。

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

相关文章

  • java与php的区别浅析

    java与php的区别浅析

    在本篇文章里小编给大家整理了关于java与php的区别以及相关知识点,有兴趣的朋友们学习下。
    2019-03-03
  • 如何为 Spring Boot 项目配置 Logback 日志

    如何为 Spring Boot 项目配置 Logback 日志

    由于 Spring Boot 的默认日志框架选用的 Logback,再加上 Log4j2 之前爆过严重的漏洞,所以我们这次就只关注 Logback,本文重点给大家介绍如何为 Spring Boot 项目配置 Logback 日志,感兴趣的朋友跟随小编一起看看吧
    2024-07-07
  • Spring MVC+FastJson+Swagger集成的完整实例教程

    Spring MVC+FastJson+Swagger集成的完整实例教程

    这篇文章主要给大家分享介绍了关于Spring MVC+FastJson+Swagger集成的完整实例教程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2018-04-04
  • 浅谈java反射和自定义注解的综合应用实例

    浅谈java反射和自定义注解的综合应用实例

    本篇文章主要介绍了java反射和自定义注解的综合应用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • Java定义队列结构,并实现入队、出队操作完整示例

    Java定义队列结构,并实现入队、出队操作完整示例

    这篇文章主要介绍了Java定义队列结构,并实现入队、出队操作,结合完整实例形式分析了java数据结构中队列的定义、入队、出队、判断队列是否为空、打印队列元素等相关操作技巧,需要的朋友可以参考下
    2020-02-02
  • Springboot自动扫描包路径来龙去脉示例详解

    Springboot自动扫描包路径来龙去脉示例详解

    这篇文章主要介绍了Springboot自动扫描包路径来龙去脉示例详解,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12
  • java 对象参数去空格方式代码实例

    java 对象参数去空格方式代码实例

    这篇文章主要介绍了java 对象参数去空格方式代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • Mybatis Interceptor线程安全引发的bug问题

    Mybatis Interceptor线程安全引发的bug问题

    这篇文章主要介绍了Mybatis Interceptor线程安全引发的bug问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • spring boot配置读写分离的完整实现步骤

    spring boot配置读写分离的完整实现步骤

    数据库配置主从之后,如何在代码层面实现读写分离?所以下面这篇文章主要给大家介绍了关于spring boot配置读写分离的完整步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2018-09-09
  • Spring Boot集成Ehcache缓存解决方式

    Spring Boot集成Ehcache缓存解决方式

    在本篇文章里小编给大家整理的是关于Spring Boot集成Ehcache缓存解决方式,需要的朋友们可以学习下。
    2019-12-12

最新评论