Search code examples
springspring-el

Use SpEl to create a bean if property is specified or a default bean if it is not


I would like to inject a Bean of type java.nio.file.Path using a user specified application property. I would like to use SpEl to do this with the use of Spring's @Value annotation so that it is achieved without need to create configuration files.

Initially I have tried this:

@Value("#{T(java.nio.file.Paths).get(\"${base.path}\") ?: T(java.nio.file.Files).createTempDirectory(\"test\")}")
private final Path path;

This works when base.path is specified in application.properties but if it is not it results in:

Could not resolve placeholder 'base.path' in value "#{T(java.nio.file.Paths).get("${base.path}") ?: T(java.nio.file.Files).createTempDirectory("test")}"

So I tried to use a conditional operator:

@Value("#{ base.path != null ? T(java.nio.file.Paths).get(\"${base.path}\") : T(java.nio.file.Files).createTempDirectory(\"test\")}")
// as well as:
@Value("#{ ${base.path} != null ? T(java.nio.file.Paths).get(\"${base.path}\") : T(java.nio.file.Files).createTempDirectory(\"test\")}")

but it still results in

Could not resolve placeholder 'base.path' in value "#{ base.path != null ? T(java.nio.file.Paths).get("${base.path}") : T(java.nio.file.Files).createTempDirectory("test")}"

I could achieve this with a configuration file but I'd like to avoid doing this:

@Configuration
@RequiredArgsConstructor
public class BasePathConfig {
    @Value("${base.path:#{null}}")
    private final String basePath;

    @Bean
    public Path basePath() throws IOException {
        if (basePath == null) {
            return Files.createTempDirectory(String.valueOf(System.currentTimeMillis()));
        }
        return Paths.get(basePath);
    }
}

Solution

  • @Value("#{'${base.path:xxxx}' != 'xxxx' " +
            "? T(java.nio.file.Paths).get('${base.path:}') " +
            ": T(java.nio.file.Files).createTempDirectory('test')}")