首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >使用 Spring BeanRegistrar 进行程序化 Bean 注册

使用 Spring BeanRegistrar 进行程序化 Bean 注册

作者头像
崔认知
发布2026-03-16 21:25:36
发布2026-03-16 21:25:36
1250
举报
文章被收录于专栏:nobodynobody

BeanRegistrar 接口适用于我们希望以程序化方式向应用上下文注册 Bean 的场景。我们可以不依赖带有 @Bean 方法的 @Configuration@Component,而是使用 BeanRegistry 抽象来动态注册 Bean。

https://docs.spring.io/spring-framework/docs/7.0.0-M3/javadoc-api/org/springframework/beans/factory/BeanRegistrar.html

1. BeanRegistrar 的优势

使用 BeanRegistrar 相比传统的基于注解的 Bean 配置,具有以下优势:

  • 细粒度控制:我们可以精确定义 Bean 的作用域、初始化策略和提供者,而不仅仅依赖注解。
  • 特定于配置文件的配置:可以根据激活的配置文件有条件地注册 Bean,实现灵活的运行时定制。
  • 延迟初始化和原型作用域:支持高级生命周期管理策略,以优化资源。
  • 支持高级运行时场景:使用 BeanRegistrar 的应用在预编译(ahead-of-time compiled)环境中可以获得更好的性能和兼容性。(参考:Spring Framework Issue 讨论)

2. 示例:使用 BeanRegistrar 进行简单的 Bean 注册

我们通过一个简单的 GreetingService 示例来演示。我们将使用 BeanRegistrar 动态注册它,而不是使用 @Service@Bean

代码语言:javascript
复制
public class GreetingService {

    privatefinal String greeting;

    public GreetingService() {
        this("Hello");
    }

    public GreetingService(String greeting) {
        this.greeting = greeting;
    }

    public String greet(String name) {
        return greeting + ", " + name + "!";
    }
}

这里,GreetingService 提供了一个可自定义的问候语。

使用 BeanRegistrar 注册 Bean

我们将创建一个配置类,导入一个自定义的注册器。

代码语言:javascript
复制
@Configuration
@Import(GreetingServiceRegistrar.class)
public class AppConfig {
}

class GreetingServiceRegistrar implements BeanRegistrar {

    @Override
    public void register(BeanRegistry registry, Environment env) {
        // 注册默认的 GreetingService
        registry.registerBean("greetingService", GreetingService.class);

        // 注册一个原型作用域、延迟初始化并带有自定义提供者的 GreetingService
        registry.registerBean("customGreetingService", GreetingService.class, spec -> spec
                .prototype()
                .lazyInit()
                .description("Custom GreetingService bean")
                .supplier(context -> new GreetingService("Hi there")));

    }
}

在这个配置中,我们首先注册了一个名为 greetingService 的默认 GreetingService。然后我们添加了第二个 Bean customGreetingService,它定义为原型作用域(每次请求都创建新实例),配置了延迟初始化(仅在首次使用时实例化),并通过一个自定义工厂提供不同的问候语。

使用已注册的 Bean

一旦 Bean 以程序化方式注册,我们就可以像其他 Spring 管理的 Bean 一样获取和使用它们。一个简单的演示方式是创建一个 CommandLineRunner,从应用上下文中获取 Bean 并执行其逻辑。

代码语言:javascript
复制
@Component
publicclass GreetingRunner implements CommandLineRunner {

    privatefinal ApplicationContext context;

    public GreetingRunner(ApplicationContext context) {
        this.context = context;
    }

    @Override
    public void run(String... args) {

        GreetingService defaultService = context.getBean("greetingService", GreetingService.class);
        GreetingService customService = context.getBean("customGreetingService", GreetingService.class);

        System.out.println(defaultService.greet("Spring Developer"));
        System.out.println(customService.greet("Spring Boot User"));

    }
}

这个运行器获取默认和自定义的 GreetingService Bean,并调用它们的 greet() 方法。默认 Bean 使用标准构造函数消息,而自定义 Bean 使用其自定义提供者提供的消息。

控制台输出

代码语言:javascript
复制
Hello, Spring Developer!
Hi there, Spring Boot User!

3. 结论

在本文中,我们探讨了如何使用 Spring 的 BeanRegistrar 以程序化方式注册具有不同作用域、延迟初始化和自定义提供者的 Bean。这种方法为开发者提供了对 Bean 注册的细粒度控制,特别适用于注解本身不足以满足需求的高级用例。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-09-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 认知科技技术团队 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. BeanRegistrar 的优势
  • 2. 示例:使用 BeanRegistrar 进行简单的 Bean 注册
  • 3. 结论
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档