dubbo多接口实现注册方案
目录(注意点和总结很重要)
背景介绍
在前后端分离情况下服务端被调用项目也分为web端app端等,但是由于项目前期接口量少,不适合做过多的项目拆分,所以才有了这一套的过渡方案,方便日后项目拆分
实现方案
dubbo默认会使用实现类的第一个接口注册成bean并集成到可远程调用接口集,所以我们要做的就是在dubbo注册bean之后集成到可远程调用接口集之前手动将该实现类的其他接口都注册成bean即可
核心方法(在后面的 DubboConfig 类里有全代码)
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
DubboClassPathBeanDefinitionScanner scanner = new DubboClassPathBeanDefinitionScanner(registry, environment, resourceLoader);
scanner.setBeanNameGenerator(new AnnotationBeanNameGenerator());
scanner.addIncludeFilter(new AnnotationTypeFilter(DubboService.class));
packagesToScan.stream().peek(scanner::scan).map(scanner::findCandidateComponents).flatMap(Set::stream).forEach(this::registerServiceBean);
}
private void registerServiceBean(BeanDefinition beanDefinition) {
Class<?> beanClass = ClassUtils.resolveClassName(beanDefinition.getBeanClassName(), classLoader);
Class<?>[] interfaceClasses = ClassUtils.getAllInterfacesForClass(beanClass);
String beanName = generateServiceBeanName(interfaceClasses[0]);
BeanDefinition bean = registry.getBeanDefinition(beanName);
for (int i = 1; i < interfaceClasses.length; i++) {
// ServiceBean Bean name
registerBeanDefinition(interfaceClasses[i], bean);
}
}
private String generateServiceBeanName(Class<?> interfaceClass) {
return ServiceBeanNameBuilder.create(interfaceClass, environment).build();
}
private void registerBeanDefinition(Class<?> interfaceClass, BeanDefinition bean) {
String replaceParamName = "interface";
AbstractBeanDefinition newBeanDefinition = BeanDefinitionBuilder.rootBeanDefinition(ServiceBean.class).getBeanDefinition();
bean.getPropertyValues().forEach(newBeanDefinition.getPropertyValues()::addPropertyValue);
newBeanDefinition.getPropertyValues().removePropertyValue(replaceParamName);
newBeanDefinition.getPropertyValues().add(replaceParamName, interfaceClass.getName());
registry.registerBeanDefinition(generateServiceBeanName(interfaceClass), newBeanDefinition);
}
代码全套
- 创建 @EnableMyDubbo 注解用于替换 @EnableDubbo 注解
import org.apache.dubbo.config.spring.context.annotation.EnableDubboConfig; import org.springframework.core.annotation.AliasFor; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented @EnableDubboConfig @MyDubboComponentScan public @interface EnableMyDubbo { @AliasFor