使用springboot开发web应用是很方便,只需要引入相对应的GAV就可以使用对应的功能,springboot默认会帮我们配置好一些常用配置。那么springboot是怎么做到的呢?这篇文章将一步步跟踪源码,查看springboot到底是如何帮我们做自动化配置。

springboot核心注解

  1. @SpringBootApplication

可以看到使用@import导入一个开启自动配置的选择器

@import的作用,官方源码,你可以把他当做是spring xml配置中的 <import resource=""/>

  1. * @author Chris Beams
  2. * @since 3.0
  3. * @see Configuration
  4. * @see ImportSelector
  5. * @see ImportResource
  6. */
  7. @Target(ElementType.TYPE)
  8. @Retention(RetentionPolicy.RUNTIME)
  9. @Documented
  10. public @interface Import {
  11.  
  12. /**
  13. * The @{@link Configuration}, {@link ImportSelector} and/or
  14. * {@link ImportBeanDefinitionRegistrar} classes to import.
  15. */
  16. Class<?>[] value();
  17. }

导入@Configuration注解的配置类
导入ImportSelector的实现类
导入ImportBeanDefinitionRegistrar的实现类

接着看导入的这个选择器(@EnableAutoConfigurationImportSelector.class)

  1. protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,
  2. AnnotationAttributes attributes) {
  3. List<String> configurations = SpringFactoriesLoader.loadFactoryNames(
  4. getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
  5. Assert.notEmpty(configurations,
  6. "No auto configuration classes found in META-INF/spring.factories. If you "
  7. + "are using a custom packaging, make sure that file is correct.");
  8. return configurations;
  9. }

这里方法调用了两个核心方法

1、 getSpringFactoriesLoaderFactoryClass(),我们发现返回的是EnableAutoConfiguration.class

2、loadFactoryNames这个方法

  1. public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
  2. String factoryClassName = factoryClass.getName();
  3. try {
  4. Enumeration<URL> urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
  5. ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
  6. List<String> result = new ArrayList<String>();
  7. while (urls.hasMoreElements()) {
  8. URL url = urls.nextElement();
  9. Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
  10. String propertyValue = properties.getProperty(factoryClassName);
  11. for (String factoryName : StringUtils.commaDelimitedListToStringArray(propertyValue)) {
  12. result.add(factoryName.trim());
  13. }
  14. }
  15. return result;
  16. }
  17. catch (IOException ex) {
  18. throw new IllegalArgumentException("Unable to load factories from location [" +
  19. FACTORIES_RESOURCE_LOCATION + "]", ex);
  20. }
  21. }

先获取factoryClass(EnableAutoConfiguration)的className(org.springframework.boot.autoconfigure.EnableAutoConfiguration),

将这个className当做Property的key值,来获取Value。springboot默认会全局扫描FACTORIES_RESOURCE_LOCATION

  1. public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";

springboot将会加载(org.springframework.boot.autoconfigure.EnableAutoConfiguration)所对应的所有自动配置到spring IOC容器中

自动配置如何生效

以(org.springframework.boot.autoconfigure.web.MultipartAutoConfiguration)为例。

我们看到当前自动配置类核心在这几个注解。

  1. @Configuration
  2. @ConditionalOnClass({ Servlet.class, StandardServletMultipartResolver.class,
  3. MultipartConfigElement.class })
  4. @ConditionalOnProperty(prefix = "spring.http.multipart", name = "enabled", matchIfMissing = true)
  5. @EnableConfigurationProperties(MultipartProperties.class)

@Configuration spring注解配置类

@ConditionalOnClass 意思是存在某个类,当前配置生效

@ConditionalOnProperty 意思是否存在开启的spring.http.multipart 的配置,这里默认开启,对应的是springboot主配置文件(application)文件中配置项目

@EnableConfigurationProperties 意思是将MultipartProperties类加入spring容器,等价于在MultipartProperties类上加 @Component注解

我们去看一下MultipartProperties类是干什么了?

  1. @ConfigurationProperties(prefix = "spring.http.multipart", ignoreUnknownFields = false)
  2. public class MultipartProperties {

@ConfigurationProperties 读取springboot主配置文件(application.prperties)的配置

所以最后发现只要满足@Conditionalxxxx条件 ,当前自动配置类即可生效。

综上,如果我们想知道引入的某个GAV可以配置哪些属性,主需要找到对应的xxxAutoConfiguration 查看对应的

@EnableConfigurationProperties(xxxx.class)引入的class即可。

【springboot】之自动配置原理的更多相关文章

  1. SpringBoot的自动配置原理过程解析

    SpringBoot的最大好处就是实现了大部分的自动配置,使得开发者可以更多的关注于业务开发,避免繁琐的业务开发,但是SpringBoot如此好用的 自动注解过程着实让人忍不住的去了解一番,因为本文的 ...

  2. SpringBoot之自动配置原理

    我在前面的Helloworld的程序中已经分析过一次,配置原理了: 1).SpringBoot启动的时候加载主配置类,开启了自动配置功能 @EnableAutoConfiguration 2).@En ...

  3. 面试题: SpringBoot 的自动配置原理

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 3.Spring Boot 的自动配置原理 package com.mmall; import org. ...

  4. SpringBoot的自动配置原理

    一.入口 上篇注解@SpringBootApplication简单分析,说到了@SpringBootApplication注解的内部结构, 其中@EnableAutoConfiguration利用En ...

  5. SpringBoot自动配置原理

    前言 只有光头才能变强. 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 回顾前面Spring的文章(以学习的顺序排好): S ...

  6. Spring Boot2 系列教程(二十一) | 自动配置原理

    微信公众号:一个优秀的废人.如有问题,请后台留言,反正我也不会听. 前言 这个月过去两天了,这篇文章才跟大家见面,最近比较累,大家见谅下.下班后闲着无聊看了下 SpringBoot 中的自动配置,把我 ...

  7. SpringBoot嵌入式Servlet配置原理

    SpringBoot嵌入式Servlet配置原理 SpringBoot修改服务器配置 配置文件方式方式修改,实际修改的是ServerProperties文件中的值 server.servlet.con ...

  8. springboot_自动配置原理

    目录 1.1 @SpringBootApplication 2.1 @EnableAutoConfiguration 2.1.1 @AutoConfigurationPackage 2.1.2 @Im ...

  9. SpringBoot实战之SpringBoot自动配置原理

    SpringBoot 自动配置主要通过 @EnableAutoConfiguration, @Conditional, @EnableConfigurationProperties 或者 @Confi ...

  10. 3. SpringBoot ——自动配置原理浅析

    SpringBoot的功能之所以强大,离不开它的自动配置这一大特色.但估计很多人只是知其然而不知其所以然.下面本人对自动配置原理做一个分析: 在使用SpringBoot时我们通过引入不同的Starte ...

随机推荐

  1. 代码精简工具lombok

    Lombok是一种通过注解的方式减少JAVA实体类中大量冗余代码,诸如get.set以及构造方法等的Java库 一.安装Lombok 步骤一 项目引入lombok插件 1 - 非maven依赖托管项目 ...

  2. 关于IEDA中的字母与数字的坑

    今天写一个demo,环境是在IDEA下写的,遇到一个关于字母与数字完全一样的坑 在jsp页面中有一个input是这样的 <input type="file" name=&qu ...

  3. sourcetree 修改文件后提交上去,文件丢失

    提交sourcetree 修改后,图片资源提交上去了,json文件没提交上去,原因是本地finder隐藏文件.gitignore_global中把一些文件类型都隐藏了不让提交. 具体使用default ...

  4. React Native - 网页组件(WebView)的使用详解

    一.WebView组件介绍 使用 WebView 组件我们可以通过 url 来加载显示一个网页,也可以传入一段 html 代码来显示.下面对其主要属性和方法进行介绍.   1,属性介绍 source: ...

  5. C#自定义事件模拟风吹草摇摆

    这是一个自定义事件的例子.C#.WinForm.Visual Studio 2017.在HoverTreeForm中画一块草地,上面有许多草(模拟).HewenqiTianyi类模拟天气,会引发“风” ...

  6. docker1

    Docker笔记 1, https://gitlab-demo.com Docker官网:https://docs.docker.com/install/overview/ 有两个版本: Docker ...

  7. python-markdown

    python-markdown无法将“`生成标签问题解决方法 2种都是代码区块 ```swift is Int ``` is Int

  8. android app内部更新适配到8.0

    app 内部跟新是app中必须要有的功能,在app出现改变时,app内部更新能以最快的速度将应用提升到最新版本. 步骤: 1.获取本地app的版本号 int versionCode = 0; try ...

  9. 20155208徐子涵《网络对抗》Exp9 Web安全基础

    20155208徐子涵<网络对抗>Exp9 Web安全基础 实验要求 本实践的目标理解常用网络攻击技术的基本原理.Webgoat实践下相关实验. 实验过程 最后一次了,没有选择尝试免考项目 ...

  10. div 隐藏显示各种例子

    <html><head><title>jquery show()</title><script type="text/javascrip ...