阳江市网站建设_网站建设公司_JSON_seo优化
2025/12/31 8:01:53 网站建设 项目流程

nats java rpc 实现类似EnableFeignClients模式

以前我简单介绍过基于nats rpc 实现类似feign 模式的访问,但是使用中并不如spring cloud feign 的方便,所以说明下如果实现类似EnableFeignClients的模式,实现bean 自动注册

实现机制

  • 原理

基本机制类似EnableFeignClients,通过import 导入一个ImportBeanDefinitionRegistrar 实现,基于bean 的自动注册基于了以前client的机制,具体是自己实现一个FactoryBean

  • EnableNatsRpcClients 实现
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(NatsRpcClientsRegistrar.class)
@Documented
public @interface EnableNatsRpcClients {String[] basePackages() default {};
}
  • NatsRpcClientsRegistrar
public class NatsRpcClientsRegistrar implements ImportBeanDefinitionRegistrar {protected ClassPathScanningCandidateComponentProvider getScanner() {return new ClassPathScanningCandidateComponentProvider(false) {@Overrideprotected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {boolean isCandidate = false;if (beanDefinition.getMetadata().isIndependent()) {if (!beanDefinition.getMetadata().isAnnotation()) {isCandidate = true;}}return isCandidate;}};}@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {Map<String, Object> attributes = importingClassMetadata.getAnnotationAttributes(EnableNatsRpcClients.class.getName());String[] basePackages = (String[]) attributes.get("basePackages");if (basePackages.length == 0) {basePackages = new String[]{importingClassMetadata.getClassName().substring(0,importingClassMetadata.getClassName().lastIndexOf("."))};}ClassPathScanningCandidateComponentProvider  scanner = getScanner();scanner.addIncludeFilter(new AnnotationTypeFilter(RpcClient.class,true));for (String basePackage : basePackages) {scanner.findCandidateComponents(basePackage).forEach(beanDef -> {try {Class<?> clazz = Class.forName(beanDef.getBeanClassName());BeanDefinitionBuilder builder =BeanDefinitionBuilder.genericBeanDefinition(NatsRpcClientFactoryBean.class);builder.addConstructorArgValue(clazz);builder.addConstructorArgReference("connection");builder.addConstructorArgReference("objectMapper");String beanName = clazz.getSimpleName();registry.registerBeanDefinition(beanName, builder.getBeanDefinition());} catch (ClassNotFoundException e) {throw new RuntimeException(e);}});}}
}
  • NatsRpcClientFactoryBean 实现

直接复用了以前的RpcServiceClient

public class NatsRpcClientFactoryBean<T> implements FactoryBean<T> {private final Class<T> rpcInterface;private final Connection connection;private final ObjectMapper objectMapper;public NatsRpcClientFactoryBean(Class<T> rpcInterface, Connection connection, ObjectMapper objectMapper) {this.rpcInterface = rpcInterface;this.connection = connection;this.objectMapper = objectMapper;}@Nullable@Overridepublic T getObject() throws Exception {T serviceClient = RpcServiceClient.builder().objectMapper(objectMapper).connection(connection).build().target(rpcInterface);return serviceClient;}@Nullable@Overridepublic Class<?> getObjectType() {return rpcInterface;}
}

参考使用

就是类似enablefeign 模式

  • 参考示例
@SpringBootApplication
@EnableNatsRpcClients(basePackages = {"com.demo.rpc"
})
  • rpc 定义
@RpcClient(serviceName = "authservice",servicePrefix = "global",serviceEndpoint = "tenantauthservicev2"
)
public interface TenantAuthApi {List<ResponseMessage<String>> auth(Message message);List<String> getRoles(Message message, Headers headers);List<String> getRoles(Message message);List<String> delteRoles(Message message, Headers headers);List<String> updateRoles(Message message, Headers headers);Object  createTenant(MyTenantModel message, Headers headers);Object  selectTenant(MyTenantModel message, Headers headers);List<ResponseMessage<String>> auth(Message message, Headers headers);List<ResponseMessage<String>> auth(String prefix,Message message);List<ResponseMessage<String>> auth(String prefix,Message message, Headers headers);
}

说明

以上是一个简单的使用,主要是通过类似feign 模式实现业务的快速开发使用,比较有意思的地方是ClassPathScanningCandidateComponentProvider ,我使用了feign 的,isCandidateComponent 方法还是很重要的,否则会有扫描不到的问题

参考资料

https://github.com/spring-cloud/spring-cloud-openfeign/blob/main/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignClientsRegistrar.java#L378

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询