我需要通过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秒的持续时间,则应将其定义为PT5S
、pt5s
或PT5s
其他示例
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
或更低的计时单位(NANOS
、MICROS
、MILLIS
、SECONDS
、MINUTES
、HOURS
)表示,因为它们表示准确的工期 - 不允许使用更高的计时单位(
DAYS
、WEEKS
、MONTHS
、YEARS
、DECADES
、CENTURIES
、MILLENNIA
、ERAS
、FOREVER
),因为它们不能代表准确的持续时间。这些ChronoUnits具有估计的持续时间,因为可能会因夏令时而改变天数,月份有不同的长度等 - 异常-Java会自动将
DAYS
转换为HOURS
,但它不会对任何其他更高的ChronoUnit(MONTHS
、YEARS
等)执行此操作
如果我们试图在;P1D";,java自动将其转换为";PT24H";。因此,如果我们想做1个月的持续时间,我们将不得不使用
PT720H
或P30D
。在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
,因此您可以在属性文件中使用PT3S
、PT1H30M
等。
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
依赖项),这导致只能使用标准转换器的一个子集。