将初始化代码添加到 Spring Boot 应用程序的正确方法是啥?

Posted

技术标签:

【中文标题】将初始化代码添加到 Spring Boot 应用程序的正确方法是啥?【英文标题】:What's the proper way to add initialization code to a Spring Boot application?将初始化代码添加到 Spring Boot 应用程序的正确方法是什么? 【发布时间】:2020-02-15 01:28:59 【问题描述】:

TLDR:我希望我的 Spring Boot 应用程序在启动时运行一些初始化代码。代码需要访问 Spring bean 和值。

我正在编写一个 Spring Boot 应用程序,它将同时使用队列中的多条消息。为此,它需要实例化多个消费者对象。 Spring 是否有很好的方法来实例化同一类的可配置数量的实例?

我必须使用的队列客户端充当线程池。它为我给它的每个消费者对象创建一个线程。消费者对象一次只接收一条消息,它们必须完全处理并确认该消息,然后才能接收另一条消息。消费者不是线程安全的,所以我不能只使用单例实例。

我考虑了以下方法,但我觉得它不合适。这似乎是对 @Component 注释的滥用,因为 Initializer 实例在构造后未使用。有什么更好的方法?

@Component
public class Initializer 

    public Initializer(ConsumerRegistry registry, @Value("$consumerCount") int consumerCount) 
        for (int i = 0; i < consumerCount; i++) 
            // Each registered consumer results in a thread that consumes messages.
            // Incoming messages will be delivered to any consumer thread that's not busy.
            registry.registerConsumer(new Consumer());
        
    


【问题讨论】:

你想用这个实现什么 How does one manage object pooling in Spring?的可能重复 可能是线程池? 我在问题中添加了更多细节。 同时来自队列的消息?你使用的是哪个队列,rabbitmq、activemq 还是 kafka Streams? 【参考方案1】:

ApplicationListener 将满足您的需求。它会收到有关已注册事件的通知,例如当 ApplicationContext 准备好时。您将拥有对所有 Bean 和注入的完全访问权限。

@Component
public class StartupApplicationListener implements ApplicationListener<ApplicationReadyEvent> 

    @Inject
    private ConsumerRegistry registry;

    @Inject
    @Value("$consumerCount")
    private int consumerCount;

    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) 
        //do your logic
        for (int i = 0; i < consumerCount; i++) 
            // Each registered consumer results in a thread that consumes messages.
            // Incoming messages will be delivered to any consumer thread that's not busy.
            registry.registerConsumer(new Consumer());
        
    

【讨论】:

以上是关于将初始化代码添加到 Spring Boot 应用程序的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

将 spring-boot-starter-security 添加到 Spring Boot 应用程序会导致错误 'entityManagerFactory' 或 'persistenceUnitNa

如何将JDBI添加到Spring Boot应用程序中?

Spring Boot 从命令行执行将文件添加到类路径

将外部 application.properties 文件添加到 tomcat 内的 dockerized spring boot web 应用程序

如何将重写规则添加到 Spring Boot 2.3.1

当我将 Spring Boot 应用程序部署到 AWS Elastic Beanstalk 并且无法从本地 Spring Boot 连接到 RDS 时出现 502 错误网关