Quarkus如何让StartupEvent监听方法仅在非PROD profile下执行
实现方案
Quarkus提供了两种常用方式实现仅非生产环境执行初始化逻辑,优先推荐构建时条件注入的方案:
方案1:@IfBuildProfile 构建时条件注册(推荐)
直接在Bean类上添加@IfBuildProfile注解,指定仅在dev、test等非生产profile下注册该Bean,生产环境构建产物中不会包含该Bean,完全避免误执行风险,修改后代码如下:
import io.quarkus.arc.profile.IfBuildProfile; import io.quarkus.runtime.StartupEvent; import jakarta.enterprise.event.Observes; import jakarta.inject.Singleton; import jakarta.transaction.Transactional; // 仅dev、test profile下会注册该Bean @Singleton @IfBuildProfile({"dev", "test"}) public class Startup { private static final String ADMIN_ROLES = String.join(",", Api.adminuser.role, Api.apiuser.role); @Inject UserRepo repo; @Transactional public void loadUsersForTest(@Observes StartupEvent evt) { repo.deleteAll(); repo.addTestUserOnly(Api.adminuser.testuser, Api.adminuser.testpassword, ADMIN_ROLES); repo.addTestUserOnly(Api.apiuser.testuser, Api.apiuser.testpassword, Api.apiuser.role); } }
方案2:运行时profile判断
如果需要保留Bean、仅在运行时动态判断是否执行逻辑,可以通过ProfileManager获取当前激活的profile,匹配生产环境时直接跳过执行:
import io.quarkus.runtime.configuration.ProfileManager; import io.quarkus.runtime.StartupEvent; import jakarta.enterprise.event.Observes; import jakarta.inject.Singleton; import jakarta.transaction.Transactional; @Singleton public class Startup { private static final String ADMIN_ROLES = String.join(",", Api.adminuser.role, Api.apiuser.role); @Inject UserRepo repo; @Transactional public void loadUsersForTest(@Observes StartupEvent evt) { // 生产环境直接跳过初始化逻辑 if ("prod".equalsIgnoreCase(ProfileManager.getActiveProfile())) { return; } repo.deleteAll(); repo.addTestUserOnly(Api.adminuser.testuser, Api.adminuser.testpassword, ADMIN_ROLES); repo.addTestUserOnly(Api.apiuser.testuser, Api.apiuser.testpassword, Api.apiuser.role); } }
两种方案对比
- 方案1在构建阶段就过滤了非必要Bean,性能更高、安全性更强,适合确定仅非生产环境需要该初始化逻辑的场景
- 方案2支持运行时动态调整,适合需要根据实际部署场景灵活开关逻辑的场景
内容的提问来源于stack exchange,提问作者Espresso
相关产品推荐
相关产品推荐

