今天研究soul_sofa相关插件
运行启动
启动TestSofaApplication后怎么都没有办法调通接口,后来上了官网看了一下文档,发现得在boostratp模块下的pom.xml文件添加以上的依赖,然后重启一下bootstrap就可以了!
<dependency>
<groupId>com.alipay.sofa</groupId>
<artifactId>sofa-rpc-all</artifactId>
<version>5.7.6</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-client</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>soul-spring-boot-starter-plugin-sofa</artifactId>
<version>${project.version}</version>
</dependency>
启动以后会注册到admin,可以查看。
在zookeeper也会注册
然后使用接口调用,成功。
以上是简单的演示,现在我们开始研究一下代码吧!
注册机制:
SoulClientController类中的这段代码用于接收sofa插件注册
@PostMapping("/sofa-register")
public String registerSofaRpc(@RequestBody final MetaDataDTO metaDataDTO) {
return soulClientRegisterService.registerSofa(metaDataDTO);
}
SoulClientRegisterServiceImpl实现了SoulClientRegisterService的registerSofa接口
@Override
public String registerSofa(final MetaDataDTO dto) {
MetaDataDO byPath = metaDataMapper.findByPath(dto.getPath());
if (Objects.nonNull(byPath)
&& (!byPath.getMethodName().equals(dto.getMethodName())
|| !byPath.getServiceName().equals(dto.getServiceName()))) {
return "you path already exist!";
}
final MetaDataDO exist = metaDataMapper.findByServiceNameAndMethod(dto.getServiceName(), dto.getMethodName());
saveOrUpdateMetaData(exist, dto);
String selectorId = handlerSofaSelector(dto);
handlerSofaRule(selectorId, dto, exist);
return SoulResultMessage.SUCCESS;
}
其中dto的类数据如下图所示。如果数据库存在该服务和方法名,则调用saveOrUpdateMetaData方法更新。handlerSofaSelector方法做的是获取选择器的id,然后调用handlerSofaRule注册规则。这样就可以把sofa的selector和rule注册到网关中。
SofaServiceBeanPostProcessor这个类实现了BeanPostProcessor,BeanPostProcessor是Spring IOC容器给我们提供的一个扩展接口。接口声明如下:
public interface BeanPostProcessor {
//bean初始化方法调用前被调用
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
//bean初始化方法调用后被调用
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
===Spring IOC容器实例化Bean===
===调用BeanPostProcessor的postProcessBeforeInitialization方法===
===调用bean实例的初始化方法===
===调用BeanPostProcessor的postProcessAfterInitialization方法===
在SofaServiceBeanPostProcessor类中的postProcessAfterInitialization调用了handler(用于处理注册的)。其中有一行代码
SoulSofaClient soulSofaClient = method.getAnnotation(SoulSofaClient.class);
这个SoulSofaClient是一个注解来的,这行代码的意思是把带有SoulSofaClient注解的方法注册到网关中,所以如果没有加SoulSofaClient注解的话就没有办法让该方法给网关代理
如果把SofaTestServiceImpl的@Service("sofaTestService")注释了,那就会导致以下问题发生,spring容器没有办法找到这个类,也没有办法完成上述行为。
有个问题,我们请求的是网关地址+appname+目的地址,这个是怎么被转发过去的,这个下一期研究。