SpringBoot基本特性以及自动化配置-SPI机制

发布于: 2020 年 06 月 07 日
SpringBoot基本特性以及自动化配置-SPI机制

一、SpringBoot概况

SpringCloud是基于SpringBoot框架,为了更好的理解后面文章的内容,这篇文章我们对SpringBoot做一个简单的介绍,算是一个技术铺垫。

1、更轻量的Web开发框架

在SpringBoot出现之前,java web应用程序基本上都是基于SpringMVC的,随着大前端的发展、容器技术的发展,SpringMVC貌似有些失群落伍,SpringMVC最大的诟病就是臃肿,程序员往往会陷入配置的泥潭,各种XML、Annotation配置,让人眼花缭乱,问题跟踪与定位也极其困难,而SpringBoot让程序员从繁杂的配置中解放出来,提供轻量级,更简便的开发框架,让开发人员聚集程序的核心业务,提升软件研发效能。

2、基于JavaConfing配置

SpringBoot在Spring的基础之上,已约定优于配置的原则,为开发人员提供更轻量、更便捷的Web开发框架。所谓约定优于配置是指:“在没有规定必须需要配置的地方,就可以使用默认配置”,大量减少需要程序员自己配置的工作,SpringBoot通过Java Config的配置方式,取代applicationContext.xml配置,实现了xml的零配置。

3、Starter包管理机制

同时,SpringBoot还引入Starter机制,Starter机制将程序某项能力所依赖的jar包进行统一管理,比如程序需要web能力,只需加入一个spring-boot-starter-web 的Starter即可,至于web开发具体需要依赖哪些jar包,并不需要程序员关心,一切都交给Starter去管理。

4、内嵌的servlet容器

在传统的Java Web程序中,系统开发完成之后,需要部署到一个Web容器(如Tomcat)上才能运行。而SpringBoot支持内嵌了servlet容器。因为有了这一特征SpringBoot可以像桌面应用程序一样,不需要依赖web容器程序独立运行,这大大提升了程序的灵活机动型,特别适合当前流行的Docker,云原生等环境。

5、自动化配置-SPI机制

在系统设计时,解耦是我们要时刻关注的一个问题,只有解耦才能实现系统的可扩展,可维护,我们熟悉的面向对象编程也好,设计模式也好,其终极目标都是为了实现高内聚低耦合。

那SPI是什么?SPI(Service Provider Interface)就是一种系统解耦的机制,SPI通过“基于接口编程”+“配置文件”来完成系统组件的动态加载,实现依赖解耦,我们知道SpringBoot所依赖的组件,只需要通过maven或者gradle引进来,应用程序就可以使用其提供的功能,那这些组件中的对象实例是如何被加载到SpringBoot,更准确的说是,如何被加载到Spring容器中来的呢?

SpringBoot定义了一套接口规范,这套规范规定:SpringBoot在启动时会扫描外部引用jar包中的META-INF/spring.factories文件,将文件中配置的类型信息加载到Spring容器(此处涉及到JVM类加载机制与Spring的容器知识),并执行类中定义的各种操作。对于外部jar来说,只需要按照SpringBoot定义的标准,就能将自己的功能装置进SpringBoot。

因此,我们可以发现,SpringBoot程序只是定义了一套加载标准,并没有具体去配置加载哪些类与接口。要加载哪些内容完全是由外部jar包自身决定的,类似Spring中IOC思想,将装配的控制权转移到了程序之外。这正是SpringBoot自动装配的核心原理。其实,并不存在什么自动装配,而是将装配控制权,要装配哪些内容放到了Jar包的spring.factories文件中了。

如果还不理解,可以想想内存条与主板的工作机制,主板定义一套接口规范,只有是按接口规范生产的内存条都可以即插即用,至于是什么品牌,什么厂家,容量大小,主板并不需要关心。

二、SpringBoot启动注解

以上对SpringBoot的基本特征做了简单的阐述,下面我们就从SpringBoot的@SpringBootApplication注解出发,具体来看看SpringBoot是如何完成容器注入的。

@SpringBootApplication组合注解

SpringBoot最顶层引用了@SpringBootApplication注解,@SpringBootApplication是一个组合注解,其里面又包括了三个重要的子注解

  • @SpringBootConfiguration

  • @ComponentScan

  • @EnableAutoCOnfiguration

我们都知道,一个应用程序的代码主要是分为两部分,一部分是程序员自己编写代码,一部分是通过外部引入的代码(如dll,jar)。SpringBoot应用程序也是如此,因此,SpringBoot的注入与启动过程也可以从两部分来看,第一部分是内部代码,第二部分是外部引入的jar包,如下图所示:

​SpringBoot 两种代码加载方式

@ComponentScan-内部代码装载

@ComponentScan注解的作用是扫描@SpringBootApplication所在的Application类(即spring-boot项目的入口类)所在的包(basepackage)下所有的@component注解(或拓展了@component的注解)标记的bean,并注入到spring容器中,是不是很绕口,没关系我们看下面的图。

@ComponentScan内部代码装载

@ComponentScan注解的扫描两个关键要素,第一是扫描的位置,第二是装配对象。

扫描位置 :扫描的默认位置(当然也可以自定义)是Main启动方法所在的类(Application),所包含的包下所有的代码,一般Application类会放在最顶层的根包里面,所有只要代码文件的目录正确,@ComponentScan能扫描到整个工程中程序员自己编写的代码。

装配对象: 扫描范围是确定了,但在这个范围下有很多Class那应该装配不装配哪些呢?这就要说到@component注解。SpringBoot会将标记了@component注解的,以及扩展了@component注解的如,@Repository、@Service、@Controller等,这些类装载进Spring容器。

@EnableAutoConfiguration-外部代码自动装载

@ComponentScan通过component注解及其子注解装载程序内部自己编写的类。这种在类上标记注解的方式显然不能用于外部引入的代码,因为没有源码文件,那外部组件的该如何装载对象呢?对于外部组件装配有两种方式,第一就是@Configuration注解,第二就是@EnableAutoConfiguration注解,这两种方式的设计思想是不一样的。

先看@EnableAutoConfiguration注解,这个注解就是SpringBoot概况中说的SPI机制的实现,通过@EnableAutoConfiguration注解,SpringBoot会扫描所有引用jar中的spring.factories配置文件,并装载文件中配置的类,整个过程程序员是不需要做任何配置,因此叫Auto Configuration自动配置。

@SpringBootConfiguration-外部代码配置装载

@EnableAutoConfiguration注解的作用是实现自动配置,而@SpringBootConfiguration注解也可以用来装载外部组件,但是,这是需要程序员手动配置来实现的,@SpringBootConfiguration继承自@Configuration,是一个Java Config,Spring会将该类中以@Bean注解标注的方法实例纳入Spring容器中,实例名就是方法名。

三、总结

我们介绍了SpringBoot的基本概况,SpringBoot是一个基于Spring,更轻量级的Web开发框架,它提供了诸如,JavaConfig、Starter包管理,内嵌Servlet容器,自动配置等许多新特征,使之成为了Java平台Web开发的首选。

我们基于SpringBoot类装载机制,讨论了三个重点注解,@ComponentScan,@EnableAutoConfiguration和@SpringBootConfiguration,这三种注解分别代表了三种不同的装载方式。

发布于: 2020 年 06 月 07 日 阅读数: 20
用户头像

攀岩飞鱼

关注

任何一步都不会决定成功,但可以决定失败! 2017.10.19 加入

记录技术,项目,管理,读书,挣钱,养娃等点点滴滴可以记录的事情。

评论

发布
暂无评论
SpringBoot基本特性以及自动化配置-SPI机制