SpringBoot中如何使用ImportBeanDefinitionRegistrar实现自定义RPC框架?
摘要:一、自定义RPC框架使用场景示例 1. 需求场景:服务注册与发现的自动配置 入口注解设计: @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented
一、自定义RPC框架使用场景示例
1. 需求场景:服务注册与发现的自动配置
入口注解设计:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(RpcComponentRegistrar.class)
public @interface EnableRpc {
// 扫描的包路径
String[] basePackages() default {};
// 注册中心类型
RegistryType registry() default RegistryType.ZOOKEEPER;
// 协议类型
ProtocolType protocol() default ProtocolType.HTTP;
}
2. RpcComponentRegistrar的多阶段注册
public class RpcComponentRegistrar implements ImportBeanDefinitionRegistrar, EnvironmentAware {
private Environment environment;
@Override
public void setEnvironment(Environment environment) {
this.environment = environment;
}
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata,
BeanDefinitionRegistry registry
) {
// 阶段1:解析配置
AnnotationAttributes attributes = AnnotationAttributes.fromMap(
importingClassMetadata.getAnnotationAttributes(EnableRpc.class.getName()));
// 阶段2:根据配置动态注册核心组件
registerRegistryCenter(registry, attributes);
registerProtocolProcessor(registry, attributes);
registerLoadBalancer(registry, attributes);
// 阶段3:扫描并注册服务提供者和消费者
scanAndRegisterServices(registry, attributes);
}
private void registerRegistryCenter(
BeanDefinitionRegistry registry,
AnnotationAttributes attributes
) {
RegistryType type = attributes.getEnum("registry");
RootBeanDefinition beanDefinition = new RootBeanDefinition();
beanDefinition.setBeanClassName(getRegistryClassByType(type));
// 从Environment读取配置(如zookeeper地址)
beanDefinition.getPropertyValues().add("address",
environment.getProperty("rpc.registry.address"));
registry.registerBeanDefinition("rpcRegistryCenter", beanDefinition);
}
private void scanAndRegisterServices(
BeanDefinitionR
