赞
踩
SPI ,全称为 Service Provider Interface,是一种服务发现机制,这一机制被广大厂商和插件所使用。 SPI 的本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类。在我们的系统中有各个抽象的模块,而往往该模块会有很多不同的实现方案,比如:
它通过在ClassPath路径下的META-INF/services文件夹查找文件,自动加载文件里所定义的类的,在面向对象的设计中,我们一般推荐模块之间基于接口编程,而且模块之间不会对实现类进行硬编码,因为一旦代码里涉及到具体的实现类,就会违反了可插拔的原则。所以为了实现在模块装配的时候不用再程序里动态指明,这就需要SPI这一种服务发现机制。
这一机制为很多框架扩展提供了可能,比如在Dubbo、JDBC、Web容器(Tomcat、Jetty)、Spring中都使用到了SPI机制,不过Dubbo和Spring不是使用的Java原生的SPI机制,而是将其重写封装或增强成为他们自己的SPI。而在了解SPI的过程中,我们会碰到打破双亲委派机制的做法,也正是因为打破了双亲委派机制,我们才能够做到SPI。若想详细了解如何打破双亲委派机制,请看之前的文章。
疑问一:springmvc怎样才能不使用springmvc.xml配置文件,从而配置springmvc呢?
答:通过JavaConfig方式,即通过注解@Configuration及编程式方式来配置。
疑问二:springmvc怎样才能不使用web.xml文件,从而配置web容器呢?
答:通过Java的SPI机制,实现 WebApplicationInitializer接口,将servlet-mapping、filter-mapping、listener在实现类里配置。
那么通过JavaConfig方式和Java的SPI机制就能够实现springmvc的零配置
tomcat web容器 遵循servlet规范,所以成为了web容器。
在servlet规范3.0里, 为了支持可以不使用web.xml,提供了ServletContainerInitializer接口,描述了在项目根目录下的META-INF文件夹下的services文件夹下的javax.servlet.ServletContainerInitializer文件里的 类的全限定名,该类只需要实现ServletContainerInitializer,就可以实现零配置启动。这种就是使用了java的SPI机制。
Tomcat所用的SPI类是WebappServiceLoader
因为这个类@HandlesTypes注解的是WebApplicationInitializer.class,Servlet3.0容器会自动的扫描classpath下面所有的WebApplicationInitializer接口的实现类,并提供给SpringServletContainerInitializer的onStartup()方法
使用Java的原生SPI机制的步骤有三:
要使用Java的原生SPI主要得用到ServiceLoader类
① 项目一:创建一个类LogInvoke【调用方】来使用ServiceLoader类,并创建一个接口Log【标准服务接口】。
关键:ServiceLoader.load(Log.class),该Log.class表示的就是需要交给其他开发者去扩展的接口
public class LogInvoke {
public static Log getLog(){
Log log = null;
ServiceLoader<Log> serviceLoader
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。