问题
I need to define Duration value (spring.redis.timeout) by application.properties.
I was trying to use one point defined in Spring boot documentation:
Spring Boot has dedicated support for expressing durations. If you expose a java.time.Duration
property, the following formats in application properties are available:
A regular long representation (using milliseconds as the default unit unless a @DurationUnit
has been specified)
The standard ISO-8601 format used by java.util.Duration
A more readable format where the value and the unit are coupled (e.g. 10s means 10 seconds)
When i use spring.redis.timeout=3s Spring boot application throws this exception:
Cannot convert value of type 'java.lang.String' to required type 'java.time.Duration': no matching editors or conversion strategy found
Which would it be the best way to set a correct value to a Duration property in application.properties withs last Spring boot 2 release?
回答1:
It's possible to use @Value notation with Spring Expression Language
@Value("#{T(java.time.Duration).parse('${spring.redis.timeout}')}")
private Duration timeout;
回答2:
The Duration in the moment (Spring-Boot 2.0.4.RELEASE) it is not possible to use together with @Value notation, but it is possible to use with @ConfigurationProperties
For Redis, you have RedisProperties and you can use the configuration:
spring.redis.timeout=5s
And:
@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());
}
}
It printed (parse as 5s):
PT5S
https://docs.oracle.com/javase/8/docs/api//java/time/Duration.html#parse-java.lang.CharSequence-
回答3:
Spring Boot attempts to coerce the external application properties to the right type when it binds to the @ConfigurationProperties beans. If you need custom type conversion, you can provide a ConversionService bean (with a bean named conversionService)
See: https://docs.spring.io/spring-boot/docs/2.0.4.RELEASE/reference/htmlsingle/#boot-features-external-config-conversion
Create new ApplicationConversionService bean (it must be named conversionService ). Here you are my code tested with Spring boot 2.0.4:
@Configuration
public class Conversion {
@Bean
public ApplicationConversionService conversionService()
{
final ApplicationConversionService applicationConversionService = new ApplicationConversionService();
return applicationConversionService;
}
Here you are an example project using this approach:
https://github.com/cristianprofile/spring-data-redis-lettuce
回答4:
If your Spring-Boot version or its dependencies don't put ApplicationConversionService into context (and Spring-Boot doesn't until 2.1), you can expose it explicitly
@Bean
public ConversionService conversionService() {
return ApplicationConversionService.getSharedInstance();
}
It invokes Duration.parse
, so you may use PT3S
, PT1H30M
, etc in properties files.
来源:https://stackoverflow.com/questions/51818137/spring-boot-2-converting-duration-java-8-application-properties