How to inject java.nio.file.Path dependency using @ConfigurationProperties

5.8k Views Asked by At

I'm using Spring Boot and have the following Component class:

@Component
@ConfigurationProperties(prefix="file")
public class FileManager {

    private Path localDirectory;

    public void setLocalDirectory(File localDirectory) {
        this.localDirectory = localDirectory.toPath();
    }

...

}

And the following yaml properties file:

file:
     localDirectory: /var/data/test

I would like to remove the reference of java.io.File (of setLocalDirectory) by replacing with java.nio.file.Path. However, I receive a binding error when I do this. Is there way to bind the property to a Path (e.g. by using annotations)?

3

There are 3 best solutions below

1
On

I don't know if there is a way with annotations, but you could add a Converter to your app. Marking it as a @Component with @ComponentScan enabled works, but you may have to play around with getting it properly registered with the ConversionService otherwise.

@Component
public class PathConverter implements Converter<String,Path>{

 @Override
 public Path convert(String path) {
     return Paths.get(path);
 }

When Spring sees you want a Path but it has a String (from your application.properties), it will lookup in its registry and find it knows how to do it.

0
On

To add to jst's answer, the Spring Boot annotation @ConfigurationPropertiesBinding can be used for Spring Boot to recognize the converter for property binding, as mentioned in the documentation under Properties Conversion:

@Component
@ConfigurationPropertiesBinding
public class StringToPathConverter implements Converter<String, Path> {

  @Override
  public Path convert(String pathAsString) {
    return Paths.get(pathAsString);
  }
}
0
On

I took up james idea and defined the converter within the spring boot configuration:

@SpringBootConfiguration
public class Configuration {
    public class PathConverter implements Converter<String, Path> {

        @Override
        public Path convert(String path) {
            return Paths.get(path);
        }
    }

    @Bean
    @ConfigurationPropertiesBinding
    public PathConverter getStringToPathConverter() {
        return new PathConverter();
    }
}