springBoot 自动配置原理
在之前文章中说过,springBoot会根据jar包去添加许多的自动配置,本文就来说说为什么会自动配置,自动配置的原理时什么?
springBoot在运行SpringApplication对象实例化时,就会去加载 META-INF/spring.factories文件,就会将这个文件中的配置都加载到spring容器中。下面,我们去看看SpringApplication对象的初始化方法 initialize() 方法。
因为我们在项目启动时有用到这个对象,所以,我们可以直接从这里进入。
找到 initialize()方法,发现,在其中存在一个获取初始化参数的方法。
我们继续向下跟进。
继续跟进,我发现里面存在两个方法,第一个获取配置中的类的名字,第二个将配置中的类创建为一个个对象。
接下来,我先跟进SpringFactoriesLoader.loadFactoryNames()方法。(笔记本屏幕显示不下,所以直接拉代码过来,就不截图了)
public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) { String factoryClassName = factoryClass.getName(); try { Enumeration<URL> urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) : ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION)); List<String> result = new ArrayList<String>(); while (urls.hasMoreElements()) { URL url = urls.nextElement(); Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url)); String factoryClassNames = properties.getProperty(factoryClassName); result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames))); } return result; } catch (IOException ex) { throw new IllegalArgumentException("Unable to load [" + factoryClass.getName() + "] factories from location [" + FACTORIES_RESOURCE_LOCATION + "]", ex); } }
我发现上面使用到一个常量 FACTORIES_RESOURCE_LOCATION ,去找到这个常量。
这个常量存放了一个文件位置,而这个文件中存放的就是自动配置的一个个对象。去找到它们。
找到这些对象之后,继续执行createSpringFactoriesInstances()方法。将上面获取到的对象名称全部实例化为一个个对象。
在spring-boot-autoconfigure的包下,也同样有一个spring.factories文件,上面的文件中主要包含的是一些系统级的自动配置,而在spring-boot-autoconfigure包下的则是一些第三方的自动配置,比如下面的redis等等。
我们进入到redis去看看,我发现在其头部有一句注解@ConditionalOnClass,这个注解的意思是,只有系统中有这几个类时,才会去加载配置这个类,如果没有则不去加载配置。
在下面这个对象中,自动去加载redis的配置
而这些配置参数则时去 application.properties文件中去找的,这个文件中的基础配置在我之前的文章中有写过(springBoot application.properties 基础配置)。
以上就是springBoot的自动化配置的原理,当然,我们知道了这些原理,其实就可以模仿这种方式在项目中加入自定义的自动化配置。
最后附上一些条件注解,在上面的自动化配置中也经常使用到。
注解 | 解释 |
---|---|
@ConditionalOnBean | 当容器中有指定Bean的条件下 |
@ConditionalOnClass | 当路径下有指定类的条件下 |
@ConditionalOnExpression | 基于SqEL表达式作为判断条件 |
@ConditionalOnJava | 基于JVM版本作为判断条件 |
@ConditionalOnJndi | 在JNDI存在的条件下查找指定位置 |
@ConditionalOnMissingBean | 当容器中没有指定Bean的情况下 |
@ConditionalOnMissingClass | 当类路径下没有指定的类的条件下 |
@ConditionalOnNotWebApplication | 当前项目不是Web项目的情况下 |
@ConditionalOnProperty | 指定的属性是否有指定的值 |
@ConditionalOnResource | 类路径是否有指定的值 |
@ConditionalOnSingleCandidate | 当前指定Bean在容器中只有一个,或者虽然有多个但是指定首选的Bean |
@ConditionalOnWebApplication | 当前项目时Web项目的条件下 |
-------------------- END ---------------------
最后附上作者的微信公众号地址和博客地址
公众号:wuyouxin_gzh
Herrt灬凌夜:https://www.cnblogs.com/wuyx/
- Spring Boot核心原理-自动配置
- SpringBoot自动配置原理
- Spring Boot自动配置原理、实战
- SpringBoot学习笔记(3) Spring Boot 运行原理,自动配置
- Spring Boot之自动配置的原理
- springboot自动配置的核心原理
- Spring Boot核心原理-自动配置 以及@ConfigurationProperties 注解
- 第5章 Spring Boot自动配置原理
- SpringBoot学习_SpringMVC自动配置原理
- Spring Boot核心原理-自动配置
- spring boot自动配置原理
- Spring Boot自动配置原理(转)
- 《Spring Boot极简教程》第5章 Spring Boot自动配置原理
- [Spring Boot] 4. Spring Boot实现自动配置的原理
- Spring Boot 运行原理之自动配置
- 《Spring Boot 实战:从0到1》第3章 Spring Boot自动配置原理
- SpringBoot学习笔记(3) Spring Boot 运行原理,自动配置
- springboot自动配置原理
- 【Spring Boot 系列 自动配置原理分析】
- Spring boot实战中自动配置原理分析