> ## Documentation Index
> Fetch the complete documentation index at: https://blog.pig4cloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 告别@Conditional！Spring 7新型Bean注册方案实战

> Spring Framework 7全新流式Bean注册方案正式发布，动态配置+性能优化+原生支持三位一体，Java开发者不可错过的配置革命指南。

## 简介

从Spring Framework 7开始，Spring提供了一流的编程式Bean注册支持，通过`BeanRegistrar`接口可以以灵活高效的方式编程式注册Bean。这一新特性为开发者提供了更强大的工具来动态管理应用上下文中的Bean定义。

## BeanRegistrar接口

### 基本用法

Bean注册器实现通常通过在`@Configuration`类上使用`@Import`注解来导入：

```java theme={null}
@Configuration
@Import(MyBeanRegistrar.class)
class MyConfiguration {
}
```

> 可以利用类型级条件注解（[@Conditional](https://docs.spring.io/spring-framework/docs/7.0.0-SNAPSHOT/javadoc-api/org/springframework/context/annotation/Conditional.html)及其他变体）来有条件地导入相关的Bean注册器。

### 实现示例

Bean注册器实现使用`BeanRegistry`和`Environment` API以简洁灵活的方式编程式注册Bean。例如，它允许通过`if`表达式、`for`循环等进行自定义注册：

```java theme={null}
class MyBeanRegistrar implements BeanRegistrar {

    @Override
    public void register(BeanRegistry registry, Environment env) {
        // 基本Bean注册
        registry.registerBean("foo", Foo.class);

        // 高级Bean注册，带配置选项
        registry.registerBean("bar", Bar.class, spec -> spec
                .prototype()
                .lazyInit()
                .description("自定义描述")
                .supplier(context -> new Bar(context.bean(Foo.class))));

        // 条件Bean注册
        if (env.matchesProfiles("baz")) {
            registry.registerBean(Baz.class, spec -> spec
                    .supplier(context -> new Baz("你好，世界！")));
        }
    }
}
```

> Bean注册器支持AOT优化，无论是在JVM上还是使用GraalVM原生镜像，包括使用实例供应商的情况。

## 与传统方法的比较

### @Conditional注解的局限性

虽然`@Conditional`系列注解在条件化Bean注册中发挥了重要作用，但在复杂场景下仍存在一些限制：

1. **表达能力有限** - 无法直接使用编程结构（循环/分支/异常处理）
2. **调试困难** - 条件匹配过程对开发者不够透明，排查问题成本高

这些限制在需要动态决策、复杂条件组合或需要与运行时环境深度交互的场景中尤为明显。

### Spring 7之前的编程式注册

深入研究Spring框架源码的开发者会发现，基于`BeanDefinitionRegistry`的编程式注册机制在Spring生态系统中被广泛应用。这种模式在Spring Boot的自动配置、各类starter的条件化Bean注册以及众多Spring项目的核心实现中尤为常见。它为框架开发者提供了极高的灵活性，使得复杂的组件注册逻辑得以实现，但同时也带来了较高的使用门槛和复杂性。

<img src="https://minio.pigx.vip/oss/202503/1741872563.png" alt="1741872563" />

#### 主要方法

1. **使用BeanDefinitionRegistry**
   * 通过`BeanDefinitionRegistryPostProcessor`实现（Spring 3.0+）
   * 需要手动创建和配置`BeanDefinition`对象
   * 更冗长和复杂

```java theme={null}
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry bdr) {
    BeanDefinition definition = new RootBeanDefinition(MyClass.class);
    bdr.registerBeanDefinition("myId", definition);
}
```

2. **使用SingletonBeanRegistry**
   * 通过`ConfigurableListableBeanFactory`
   * 更简单但仅限于注册已创建的单例实例
   * 对Bean定义属性的控制有限

```java theme={null}
ConfigurableListableBeanFactory beanFactory =
    ((ConfigurableApplicationContext) applicationContext).getBeanFactory();
beanFactory.registerSingleton(bean.getClass().getCanonicalName(), bean);
```

## 优势与展望

Spring Framework 7的新编程式Bean注册相比之前的方法是一个显著改进，新方法简化了常见的注册模式，遵循Spring提供更现代、对开发者友好的API的趋势，同时保持与现有方法的向后兼容性。
