一、什么是springboot自动配置springboot通过@enableautoconfiguration注解开启自动配置,对jar包下的spring.factories文件进行扫描,这个文件中包含了可以进行自动配置的类,当满足@condition注解指定的条件时,便在依赖的支持下进行实例化,注册到spring容器中。
通俗的来讲,我们之前在写ssm项目时候,配置了大量坐标和配置内容,搭环境的过程在项目开发中占据了大量时间,springboot的最大的特点就是简化了各种xml配置内容,所以springboot的自动配置就是用注解来对一些常规的配置做默认配置,简化xml配置内容,使你的项目能够快速运行。
springboot核心配置原理:
自动配置类都存放在spring-boot-autoconfigure-版本号.jar下的org.springframework.boot.autoconfigure中
当我们在application.properties中配置debug=true后启动容器。可以看到服务器初始化的初始化配置
dispatcherservletautoconfigratio注册前端控制器
embeddedservletcontainerautoconfiguration注册容器类型
httpmessageconvertersautoconfiguration注册json或者xml处理器
jacksonautoconfiguration注册json对象解析器
如果加入其他功能的依赖,springboot还会实现这些功能的自动配置
二、starter组件starter组件是可被加载在应用中的maven依赖项项。只有在maven配置中添加对应的依赖配置,即可使用对应的starter组件。例如,添加spring-boot-starter-web依赖,就可以用于构建restapi服务,其包含了springmvc和tomcat内嵌容器。
一个完整的starter组件包括以下两点:
提供自动配置功能的自动配置模块
提供依赖关系管理岗功能的组件模块,即封装了组件所有功能,开箱即用。
spring-boot-starter-web依赖源码
package org.springframework.boot.autoconfigure.web.servlet;@configuration@conditionalonclass({servletrequest.class})@conditionalonwebapplication( type = type.servlet)@enableconfigurationproperties({serverproperties.class})@import({servletwebserverfactoryautoconfiguration.beanpostprocessorsregistrar.class})public class servletwebserverfactoryautoconfiguration { ......}@
三、三大注解@springbootconfiguration:继承自configuration,支持javaconfig的方式进行配置。
@enableautoconfiguration:本文重点讲解,主要用于开启自动配置。
@componentscan:自动扫描组件,默认扫描该类所在包及其子包下所有带有指定注解的类,将它们自动装配到bean容器中,会被自动装配的注解包括@controller、@service、@component、@repository等。也可以指定扫描路径。
四、@enableautoconfiguration这个注解是帮助我们自动加载默认配置的,它里面有两个关键注解@autoconfigurationpackage和@import,我们来详细了解@import注解。
@override public string[] selectimports(annotationmetadata annotationmetadata) { //检查自动配置功能是否开启,默认开启 if (!isenabled(annotationmetadata)) { return no_imports; } //加载自动配置的元信息 autoconfigurationmetadata autoconfigurationmetadata = autoconfigurationmetadataloader .loadmetadata(this.beanclassloader); annotationattributes attributes = getattributes(annotationmetadata); //获取候选配置类 list<string> configurations = getcandidateconfigurations(annotationmetadata, attributes); //去掉重复的配置类 configurations = removeduplicates(configurations); //获得注解中被exclude和excludename排除的类的集合 set<string> exclusions = getexclusions(annotationmetadata, attributes); //检查被排除类是否可实例化、是否被自动注册配置所使用,不符合条件则抛出异常 checkexcludedclasses(configurations, exclusions); //从候选配置类中去除掉被排除的类 configurations.removeall(exclusions); //过滤 configurations = filter(configurations, autoconfigurationmetadata); //将配置类和排除类通过事件传入到监听器中 fireautoconfigurationimportevents(configurations, exclusions); //最终返回符合条件的自动配置类的全限定名数组 return stringutils.tostringarray(configurations);
@import(autoconfigurationimportselector.class)注解,这里导入autoconfigurationimportselector类。这个类中有一个非常重要的方法——selectimports(),它几乎涵盖了组件自动装配的所有处理逻辑,包括获得候选配置类、配置类去重、排除不需要的配置类、过滤等,最终返回符合条件的自动配置类的全限定名数组。
五、springfactoriesloaderspring-core包里定义了springfactoriesloader类,这个类实现了检索meta-inf/spring.factories文件,并获取指定接口的配置的功能。在这个类中定义了两个对外的方法:
loadfactories根据接口类获取其实现类的实例,这个方法返回的是对象列表。
loadfactorynames根据接口获取其接口类的名称,这个方法返回的是类名的列表。
上面的两个方法的关键都是从指定的classloader中获取spring.factories文件,并解析得到类名列表,具体代码如下:
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); }}
由代码可知,在这个方法中会遍历整个classloader中所有jar包下的spring.factories文件。也就是说我们可以在自己的jar中配置spring.factories文件,不会影响到其它地方的配置,也不会被别人的配置覆盖。
spring.factories的是通过properties解析得到的,所以我们在写文件中的内容都是安装下面这种方式配置的:
com.xxx.interface=com.xxx.classname
以上就是springboot自动配置的实现原理是什么的详细内容。