如何有条件地不在Spring Boot中创建bean?

时间:2019-10-31 09:46:10

标签: spring spring-boot testing javabeans

在我的应用程序中,我有一个组件,可以在启动应用程序时从其他系统读取数据。 但是,在测试期间,我不希望创建此组件

@Component
@Slf4j
public class DeviceStatisticsSyncHandler {
    @EventListener
    public void handle(ApplicationReadyEvent event) {
        syncDeviceStatisticsDataSync();
    }

    @Value("${test.mode:false}")
    public  boolean serviceEnabled;
}

我可以使用条件来解决这个问题,但是其他代码阅读者需要理解,所以我认为这不是一个很好的方法:

@EventListener(condition =  "@deviceStatisticsSyncHandler .isServiceEnabled()")
public void handle(ApplicationReadyEvent event) {
    syncDeviceStatisticsDataSync();
}

public  boolean isServiceEnabled() {
    return !serviceEnabled;
}

@Value("${test.mode:false}")
public  boolean serviceEnabled;

我的应用程序不使用个人档案,是否有其他方法可以解决此问题。

Spring Boot版本:2.1.3

2 个答案:

答案 0 :(得分:1)

一种可能的选择是,如果您处于测试模式,则根本不加载DeviceStaticsticsSyncHandler。 这里的“ test.mode”不是一个好名字,因为生产代码包含与测试紧密绑定的内容。

以下方法如何?

@Component
@ConditionalOnProperty(name ="device.stats.handler.enabled", havingValue = "true", matchIfMissing=true) 
public class DeviceStatisticsSyncHandler {
   // do whatever you need here, but there is no need for "test.mode" enabled related code here
}

现在在“测试”中,您可以在测试本身上定义测试属性“ device.stats.handler.enabled = false”,甚至可以将该定义放置在src/test/reources/application.properties中,因此对于所有测试,它都将是false在模块中。

一个明显的优点是,此定义几乎可以自我解释,并且可以由其他项目维护人员轻松理解。

答案 1 :(得分:1)

对我而言,情况并非如此,而是与环境有关。我将使用spring型材解决这个问题。

步骤1:首先创建一个界面

public interface DeviceStatisticsSyncHandler {

    public void handle(ApplicationReadyEvent event);
}

第2步:创建用于生产的实现

@Component
@Profile("!test")
public class DeviceStatisticsSyncHandlerImpl implements DeviceStatisticsSyncHandler {
            @EventListener
            @Override
            public void handle(ApplicationReadyEvent event) {
                syncDeviceStatisticsDataSync();
            }
        }

第3步:创建测试的实现

@Component
 @Profile("test")
 public class DeviceStatisticsSyncHandlerTestImpl implements DeviceStatisticsSyncHandler {
                @EventListener
                @Override
                public void handle(ApplicationReadyEvent event) {
                    //do Nothing
                }
}

最后一步

您需要做的就是设置/切换属性

-Dspring.profiles.active=test 

-Dspring.profiles.active=prod