Spring boot 2转换持续时间java 8 application.properties



我需要通过application.properties.定义持续时间(spring.redis.timeout)

我试图使用Spring引导文档中定义的一点:

Spring Boot专门支持表达持续时间。如果公开java.time.Duration属性,则应用程序属性中的以下格式可用:

规则的长表示形式(除非指定了@DurationUnit,否则使用毫秒作为默认单位)java.util.Duration使用的标准ISO-8601格式一种更可读的格式,其中值和单位耦合(例如,10s表示10秒)

当我使用spring.redis.timeout=3s时,spring引导应用程序抛出以下异常:

无法将"java.lang.String"类型的值转换为所需类型"java.time.Duration":找不到匹配的编辑器或转换策略

在上一个Spring boot 2版本的application.properties中,为Duration属性设置正确值的最佳方式是什么?

任何类型为duration的属性都可以通过.properties.yml文件注入。你所需要做的就是使用正确的格式。

如果要注入5秒的持续时间,则应将其定义为PT5Spt5sPT5s

字母的大小写无关紧要,所以您可以使用任何可读的组合
  • 通常每个人都使用所有大写字母
  • 其他示例

    PT1.5S       = 1.5 Seconds
    PT60S        = 60 Seconds
    PT3M         = 3 Minutes
    PT2H         = 2 Hours
    P3DT5H40M30S = 3Days, 5Hours, 40 Minutes and 30 Seconds
    

    你也可以用+ve和-ve符号来表示一段时间的正负。

    • 你只能否定其中一个实体,例如:PT-3H30M=-3小时,+30分钟,基本上是-2.5小时
    • 或者你可以否定整个实体:-PT3H30M=-3小时,-30分钟,基本上是-3.5小时
    • 双负在这里也有效:-PT-3H+30M=+3小时,-30分钟,基本上是+2.5小时

    注意:

    • 工期只能用HOURS或更低的计时单位(NANOSMICROSMILLISSECONDSMINUTESHOURS)表示,因为它们表示准确的工期
    • 不允许使用更高的计时单位(DAYSWEEKSMONTHSYEARSDECADESCENTURIESMILLENNIAERASFOREVER),因为它们不能代表准确的持续时间。这些ChronoUnits具有估计的持续时间,因为可能会因夏令时而改变天数,月份有不同的长度等
    • 异常-Java会自动将DAYS转换为HOURS,但它不会对任何其他更高的ChronoUnit(MONTHSYEARS等)执行此操作

    如果我们试图在;P1D";,java自动将其转换为";PT24H";。因此,如果我们想做1个月的持续时间,我们将不得不使用PT720HP30D。在P30D的情况下,将进行java的自动转换,并向我们提供PT720H


    如果它对你有效或你喜欢解释,请投票支持。谢谢,

    Spring Boot 2.5.5的更新


    我们可以将@Value注释与application.properties值一起使用。例如,您的application.properties文件中有下一个属性:

    your.amazing.duration=100ms
    

    然后您可以在@Value注释中使用它:

    @Value("${your.amazing.duration}") 
    final Duration duration;
    

    仅此而已。


    支持的单位:

    • ns纳秒
    • us微秒
    • 毫秒
    • s持续秒
    • m分钟
    • h持续数小时
    • d

    文档:链接

    可以将@Value表示法与Spring表达式语言一起使用

    @Value("#{T(java.time.Duration).parse('${spring.redis.timeout}')}")
    private Duration timeout;
    

    当前持续时间(Spring Boot 2.0.4.RELEASE)不能与@Value表示法一起使用,但可以与@ConfigurationProperties 一起使用

    对于Redis,您有RedisProperties,可以使用配置:

    spring.redis.timeout=5s
    

    和:

    @SpringBootApplication
    public class DemoApplication {
    @Autowired
    RedisProperties redisProperties;
    public static void main(String[] args) {
    SpringApplication.run(DemoApplication.class, args);
    }
    @PostConstruct
    void init() {
    System.out.println(redisProperties.getTimeout());
    }
    }
    

    打印(解析为5s):

    PT5S
    

    https://docs.oracle.com/javase/8/docs/api//java/time/Duration.html#parse-java.lang.CharSequence-

    如果您的Spring Boot版本或其依赖项没有将ApplicationConversionService放入上下文中(而Spring Boot直到2.1才将其显式公开

    @Bean
    public ConversionService conversionService() {
    return ApplicationConversionService.getSharedInstance();
    }
    

    它调用Duration.parse,因此您可以在属性文件中使用PT3SPT1H30M等。

    Spring Boot在绑定到@ConfigurationProperties bean时,试图将外部应用程序属性强制为正确的类型。如果您需要自定义类型转换,您可以提供ConversionServicebean(带有名为ConversionService的bean)

    请参阅:https://docs.spring.io/spring-boot/docs/2.0.4.RELEASE/reference/htmlsingle/#boot-具有外部配置转换

    创建新的ApplicationConversionServicebean(它必须命名为conversionService)。这是我用Spring boot 2.0.4测试的代码:

    @Configuration
    public class Conversion {
    @Bean
    public ApplicationConversionService conversionService()
    {
    final ApplicationConversionService applicationConversionService = new ApplicationConversionService();
    return applicationConversionService;
    }
    

    这里有一个使用这种方法的示例项目:

    https://github.com/cristianprofile/spring-data-redis-lettuce

    我得到了这个错误,但只是在测试期间使用@Value注释的Duration的bean在其他方面也起作用。事实证明,我缺少测试用例类上的@SpringBootTest注释(以及提供它的spring-boot-test依赖项),这导致只能使用标准转换器的一个子集。

    相关内容

    • 没有找到相关文章

    最新更新