服务提供者接口,通过在classPath路径下文件夹查找文件并自动加载文件里所定义的类。
Java中连接数据库
加载驱动,通过driverManger获取connection连接对象,创建statement对象创建SQL语句,最后再处理结果集。驱动不同而且只是一个接口,不可以直接实例化,除非知道接口的全限定名,通过反射。
SPI解决不同框架之间的扩展问题。
springBoot自动装配
其他框架的包名不同不能扫描注入,解耦,读取spring.factories文件,加载到IOC中。
总结:
1.SPI机制能够使接口和具体的实现类解耦,根据实际情况启用或替换组件;
2.为框架提供扩展的可能。
3.SPI是一种思想。
Java的SPI机制
Java中提供了DriverManger、Connection,Statement接口,来约定了JDBC规范。但针对MySQL或Oracle数据库来说,需要指明具体的驱动包,比如MySQL:
MySQL.jar包中的META-INF/services下的java.sql.Driver文件,文件中指明了具体的驱动类
com.mysql.cj.jdbc.Driver
这样Java会读取该jar包下的文件,那Java怎么找到该文件?因为Java程序需要该类:java.sql.Driver,所以找文件名是java.sql.Driver的文件。-------相当于是加载了Driver接口的具体的实现类。
SPI机制的缺点:文件中所有类都会被加载且被实例化。没有办法指定某一个类来加载和实例化。
此时dubbo的SPI可以解决。
dubbo的SPI机制
dubbo⾃⼰实现了⼀套SPI机制来解决Java的SPI机制存在的问题。
dubbo源码中有很多的项⽬,每个项⽬被打成⼀个jar包。⽐如代码中通过@Service注解的属
性protocol="c1"找到application.properties的c1协议是rest,那么就会去rest项⽬中找该项
⽬中的META-INF中对应的⽂件,再找到指定的类来加载。
rest=org.apache.dubbo.rpc.protocol.rest.RestProtocol
通过这种机制,在项目中新增一个协议也非常方便:
(1)项目中新增协议jar;
(2)在application.properties中加入协议名称;
(3)在新增的项目的META-INF/services文件中加入配置。