1、SPI机制:Service Provider Interface:服务提供发现机制,类型IOC
Java SPI实现:ServiceLoader
定义接口A;
实现接口A的实现类,B和C;
在/META-INF/services/下创建文件,文件名为A类的全名称,内容为B和C的类全名
调用:
ServiceLoader<A> load = ServiceLoader.load(A.class);
Interator<A> i=load.iterator();
原理:根据类全名拿到实例队形,反射实现
作用:JDBC这种,允许第三方提供实现,例:sun定义接口,由对应厂商实现对于接口,违反了双亲委派机制;
缺点:只能通过遍历获取,且会全部实例化;
Dubbo SPI:ExtensionLoader
特点:可根据接口类名和key值获取具体实现,K-V值方式;可对扩展类实例的属性进行依赖注入IOC;可采用装饰器模式实现AOP;
Dubbo SPI与Java的不同,用的是ExtensionLoader(扩展类加载器),Dubbo内部的动态代理方式,负载均衡策略,RPC协议,拦截器,容器,注册中心类型都是使用SPI
注解@Spi:是对接口的注解,Dubbo内部组件都是通过spi方式管理与解耦,spi文件放在/META-INF/dubbo/路径下
Dubbo SPI步骤:
通过getExtensionClass获取拓展类(先从缓存拿,拿不到再加载)
反射创建拓展对象
向拓展对象注入依赖,IOC通过setter方法依赖注入
将拓展对象放在对应的wrapper对象中
示例:
接口A 实现类B、C;
配置文件A中:b=B(全名),b是B的别名 c=C(全名),c是C的别名
调用:
ExtensionLoader<A> e = ExtensionLoader.getExtensionLoader(A.class);
A a1 = e.getExtension("b");
A a2 = e.getExtension("c");
Dubbo和JDK的SPI都是懒加载,双重检索机制
Spring SPI:SpringFoctoriesLoader
不必要key是接口,值是实现类;例如:springboot中key是注解@EnableAutoConfiguration,值是被@Configuration标记的类;/MERA-INF/spring.faotories
spring.factories是spi机制,在/MERA-INF/spring.faotories配置接口的实现类型名称,然后在程序中读取这些配置并实例化。
spring-core定义SpringFactoriesLoader类用于检索spring.factories文件,该类中定义了两个对外方法:
loadFactories:根据接口类获取其实现类的实例,这个方法返回队形列表
loadFactoryNames:根据接口回去类的名称,返回的是类名的接口
BeanPostProcessor接口:spring ioc容器提供的接口,接口有两个方法(before、after),需要在spring容器完成bean初始化前后添加自己的逻辑处理,可以定义该接口的实现类