子非 發表於 2026-2-27 09:23:00

springboot~ImportBeanDefinitionRegistrar在自定义RPC框架中的使用

<h2 id="一自定义rpc框架使用场景示例">一、自定义RPC框架使用场景示例</h2>
<h3 id="1-需求场景服务注册与发现的自动配置">1. 需求场景:服务注册与发现的自动配置</h3>
<p><strong>入口注解设计:</strong></p>
<pre><code class="language-java">@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;
}
</code></pre>
<h3 id="2-rpccomponentregistrar的多阶段注册">2. RpcComponentRegistrar的多阶段注册</h3>
<pre><code class="language-java">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(
      BeanDefinitionRegistry registry,
      AnnotationAttributes attributes
    ) {
      // 1. 扫描@ServiceProvider注解的服务提供者
      Set&lt;BeanDefinition&gt; providers = scanForAnnotations(
            attributes.getStringArray("basePackages"),
            ServiceProvider.class);
      
      // 2. 为每个服务提供者注册特殊的BeanDefinition
      for (BeanDefinition providerDef : providers) {
            GenericBeanDefinition enhancedDef = enhanceForProvider(providerDef);
            registry.registerBeanDefinition(
                providerDef.getBeanClassName(),
                enhancedDef);
            
            // 3. 同时自动注册到服务注册中心
            registerToServiceDiscovery(providerDef);
      }
      
      // 4. 扫描@RpcReference注解的消费方
      // 需要创建ReferenceBeanFactoryBean来处理动态代理
      registerReferenceProcessor(registry, attributes);
    }
   
    private GenericBeanDefinition enhanceForProvider(BeanDefinition originalDef) {
      GenericBeanDefinition definition = new GenericBeanDefinition(originalDef);
      
      // 添加服务暴露的初始化逻辑
      definition.setInitMethodName("exportService");
      
      // 添加后置处理器来监听服务状态
      definition.getPropertyValues().add("serviceRegistry",
            new RuntimeBeanReference("rpcRegistryCenter"));
      
      return definition;
    }
   
    private void registerReferenceProcessor(
      BeanDefinitionRegistry registry,
      AnnotationAttributes attributes
    ) {
      // 创建处理@RpcReference注解的后置处理器
      RootBeanDefinition processorDef = new RootBeanDefinition(
            RpcReferenceAnnotationBeanPostProcessor.class);
      
      // 注入必要的依赖
      processorDef.getPropertyValues().add("registryCenter",
            new RuntimeBeanReference("rpcRegistryCenter"));
      processorDef.getPropertyValues().add("loadBalancer",
            new RuntimeBeanReference("rpcLoadBalancer"));
      
      registry.registerBeanDefinition(
            "rpcReferenceAnnotationBeanPostProcessor",
            processorDef);
    }
}
</code></pre>
<h3 id="3-rpc框架的关键扩展点设计">3. RPC框架的关键扩展点设计</h3>
<p><strong>服务消费者代理工厂:</strong></p>
<pre><code class="language-java">public class RpcReferenceFactoryBean implements FactoryBean&lt;Object&gt; {
   
    private Class&lt;?&gt; interfaceType;
    private String serviceName;
    private LoadBalancer loadBalancer;
   
    @Override
    public Object getObject() throws Exception {
      // 创建动态代理,实现RPC调用
      return Proxy.newProxyInstance(
            interfaceType.getClassLoader(),
            new Class&lt;?&gt;[] {interfaceType},
            new RpcInvocationHandler(serviceName, loadBalancer)
      );
    }
   
    @Override
    public Class&lt;?&gt; getObjectType() {
      return interfaceType;
    }
}
</code></pre>
<p><strong>注解处理器:</strong></p>
<pre><code class="language-java">public class RpcReferenceAnnotationBeanPostProcessor
    implements BeanPostProcessor, BeanFactoryAware {
   
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
      // 扫描bean中所有@RpcReference注解的字段
      Field[] fields = bean.getClass().getDeclaredFields();
      for (Field field : fields) {
            if (field.isAnnotationPresent(RpcReference.class)) {
                RpcReference reference = field.getAnnotation(RpcReference.class);
               
                // 为每个引用创建代理并注入
                Object proxy = createProxy(field.getType(), reference);
                field.setAccessible(true);
                try {
                  field.set(bean, proxy);
                } catch (IllegalAccessException e) {
                  throw new RuntimeException(e);
                }
            }
      }
      return bean;
    }
}
</code></pre>
<h2 id="二架构师的设计模式总结">二、架构师的设计模式总结</h2>
<h3 id="1-动态注册模式">1. 动态注册模式</h3>
<p><strong>模板方法流程:</strong></p>
<pre><code>1. 解析注解元数据(AnnotationMetadata)
2. 根据元数据创建或选择BeanDefinition
3. 修改BeanDefinition(替换BeanClass、添加构造参数)
4. 批量注册到Registry
</code></pre>
<h3 id="2-策略模式的应用">2. 策略模式的应用</h3>
<pre><code class="language-java">// 根据配置动态选择实现类
private String getRegistryClassByType(RegistryType type) {
    switch (type) {
      case ZOOKEEPER: return "com.rpc.registry.ZookeeperRegistry";
      case NACOS: return "com.rpc.registry.NacosRegistry";
      case ETCD: return "com.rpc.registry.EtcdRegistry";
      default: throw new IllegalArgumentException();
    }
}
</code></pre>
<h3 id="3-装饰器模式的使用">3. 装饰器模式的使用</h3>
<pre><code class="language-java">// 增强原始BeanDefinition
private GenericBeanDefinition enhanceForProvider(BeanDefinition originalDef) {
    GenericBeanDefinition definition = new GenericBeanDefinition(originalDef);
   
    // 装饰1:添加初始化方法
    definition.setInitMethodName("exportService");
   
    // 装饰2:添加销毁方法
    definition.setDestroyMethodName("unexportService");
   
    // 装饰3:添加服务版本属性
    definition.getPropertyValues().add("version", "1.0.0");
   
    return definition;
}
</code></pre>
<h2 id="三扩展性设计">三、扩展性设计</h2>
<pre><code class="language-java">// 允许通过SPI扩展组件
private void registerExtensions(BeanDefinitionRegistry registry) {
    ServiceLoader&lt;RpcExtension&gt; loader = ServiceLoader.load(RpcExtension.class);
    for (RpcExtension extension : loader) {
      RootBeanDefinition def = new RootBeanDefinition(extension.getClass());
      registry.registerBeanDefinition(
            extension.extensionName(),
            def
      );
    }
}
</code></pre>
<h2 id="四与spring-boot-autoconfiguration的对比">四、与Spring Boot AutoConfiguration的对比</h2>
<table>
<thead>
<tr>
<th>特性</th>
<th>ImportBeanDefinitionRegistrar</th>
<th>@Configuration + @Bean</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>注册时机</strong></td>
<td>更早(在ConfigurationClassParser阶段)</td>
<td>稍晚(BeanFactoryPostProcessor之后)</td>
</tr>
<tr>
<td><strong>动态性</strong></td>
<td>可根据元数据动态决定注册哪些Bean</td>
<td>静态声明,条件化需借助@Conditional</td>
</tr>
<tr>
<td><strong>批量处理</strong></td>
<td>天然支持批量扫描和注册</td>
<td>需要手动遍历或使用@Import多个配置</td>
</tr>
<tr>
<td><strong>Bean定义修改</strong></td>
<td>可直接操作BeanDefinition</td>
<td>只能创建新的BeanDefinition</td>
</tr>
<tr>
<td><strong>适用场景</strong></td>
<td>框架集成、注解驱动、插件化</td>
<td>简单条件装配、第三方Bean声明</td>
</tr>
</tbody>
</table>
<p><strong>选择建议</strong>:</p>
<ul>
<li>当需要基于<strong>注解属性动态决定注册逻辑</strong>时,用<code>ImportBeanDefinitionRegistrar</code></li>
<li>当Bean的<strong>数量或类型在编译期无法确定</strong>时,用<code>ImportBeanDefinitionRegistrar</code></li>
<li>当只是<strong>根据条件选择性地注册几个已知Bean</strong>时,用<code>@Configuration</code> + <code>@Conditional</code>更简单</li>
</ul>


</div>
<div id="MySignature" role="contentinfo">
    <p></p>
<div class="navgood">
<p>作者:仓储大叔,张占岭,<br>
荣誉:微软MVP<br>QQ:853066980</p>

<p><strong>支付宝扫一扫,为大叔打赏!</strong>
<br><img src="https://images.cnblogs.com/cnblogs_com/lori/237884/o_IMG_7144.JPG"></p>
</div><br><br>
来源:https://www.cnblogs.com/lori/p/19645227
頁: [1]
查看完整版本: springboot~ImportBeanDefinitionRegistrar在自定义RPC框架中的使用