Spring Boot @ConditionalOnProperty行为

时间:2015-08-31 18:10:44

标签: spring spring-boot

我试图理解为什么以下代码会因以下异常而中断:

@Configuration
@EnableMetrics(proxyTargetClass = true)
public class MetricsConfig {

//................

    @Bean
    @ExportMetricWriter
    public MetricWriter statsdMetricWriter() {

        return new StatsdMetricWriter("13.127.9.150",8125);
     }

}
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'statsdMetricWriter' defined in class path resource [demo/MetricsConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.actuate.metrics.writer.MetricWriter]: Factory method 'statsdMetricWriter' threw exception; nested exception is java.lang.NoClassDefFoundError: com/timgroup/statsd/StatsDClientErrorHandler

当我向statsdMetricWriter()添加注释时: @ConditionalOnProperty(prefix =“statsd”,name = {“host”,“port”})

并且提供了@ConfigurationProperties(prefix =“statsd”)公共类StatsdProperties {// ...},上面的Spring配置运行正常。

Spring机器对新的StatsdMetricWriter(String,int)不起作用的要求是什么?

更新以解决@Stéphane的困惑:

是的,这个问题一般也与Spring有关,但我在使用Spring Boot时会遇到它,因此就是那个标签。

我正在尝试将配置类添加到现有应用程序以将其指标导出到statsd服务器,并找到一些相关的示例herehere基于我构建我的拥有Configuration类。当然它并不是空的,为了简洁,我只是简单地复制了相关部分。

我不一定要使用ConditionalOnProperty,但它是上述示例的一部分,如果没有它,它似乎不起作用。

在我这方面的困惑是,即使在像这样的最小配置类中,也不应该说:

@Bean
@ExportMetricWriter
public MetricWriter statsdMetricWriter() {
    return new StatsdMetricWriter("10.101.7.130",8125);
 }

我想这么想,但上面的例外似乎与我的想法相矛盾。重新访问上述链接并使用 @ConditionalOnProperty(prefix =“statsd”,name = {“host”,“port”})(不包括类路径上的任何其他依赖项)限定工厂方法似乎消除异常。这导致了上述问题。希望能澄清一点。

更新原始问题:

根据下面的评论添加了缺少的依赖项,原始异常消失了,但我想自己澄清@ConditionalOnProperty如何运作。在我目前的设置中有一个配置bean:

@Configuration
@EnableMetrics(proxyTargetClass = true)
@EnableConfigurationProperties(StatsdProperties.class)
public class MetricsConfig {

@Value("${statsd.host:localhost}")
    private String host = "localhost";

    @Value("${statsd.port:8125}")
    private int port;

    @Autowired
    private StatsdProperties statsdProperties;

//......................

    @Bean
    @ConditionalOnProperty(prefix = "statsd", name = {"host", "port"})
    @ExportMetricWriter
    public MetricWriter statsdMetricWriter() {

        logger.info("creating statsdMetricWriter....");
        return new StatsdMetricWriter(
                statsdProperties.getPrefix(),
                statsdProperties.getHost(),
                statsdProperties.getPort()
        );
     }

}

和相关的配置属性bean:

@ConfigurationProperties(prefix = "statsd")
public class StatsdProperties {

    @Value("${statsd.host:13.127.9.150}")
    private String host;

    @Value("${statsd.port:8125}")
    private int port;

    private String prefix;

    //getters & setters

在执行@ConditionalOnProperty注释时不清楚:

  • 它如何解释属性的存在 - 它是applicationaiton.properties文件中的值存在(似乎有效),还是作为@Value注释的默认值存在的值(它不存在)在我的测试中似乎考虑到了考虑因素)?或者别的什么呢?

  • 什么是更好的做法 - 在@Configuration类中或在@ConfigurationProperties类或其他地方使用@Value?

另外,在语义上,@ ConditionalOnProperty似乎有点误导,对我来说它暗示了类中特定属性的存在。听起来真正试图断言的是@ConditionalOnPropertyValue,还是我不明白?

提前谢谢。

0 个答案:

没有答案