carlspring
carlspring

Reputation: 32717

How to use Spring's @Value without a properties file?

I currently have the following code:

int port = System.getProperty("port") != null ?
           Integer.parseInt(System.getProperty("port")) :
           8080;

I don't like this and would like to replace it with the Spring alternative. So, I thought I should use the @Value annotation. I don't want to have a properties file for this. However, I would like to have a default value via the annotation.

Is there a way to do this without a properties file and what would the proper code implementation be? Do I still need to have a PropertySourcesPlaceholderConfigurer? Could you please show me a working example of how to do this?

Upvotes: 3

Views: 1612

Answers (3)

tkachuko
tkachuko

Reputation: 1986

Tested and working.

  1. Yes, you need PropertyPlaceholderConfigurer however it does not require property file
  2. Reference your system variable like this: @Value("#{systemEnvironment['YOUR_VARIABLE_NAME'] ?: 'DEFAULT_VALUE'}"

Code sample:

package abc;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class Test {

    public final String javaPath;

    @Autowired
    public Test(@Value("#{systemEnvironment['Path']}") String javaPath) {
        this.javaPath = javaPath;
    }
}

Configuration:

@Configuration
@ComponentScan("abc")
public class Config {

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }
}

Running all the sample:

public class Runner {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
        Test bean = context.getBean(Test.class);
        System.out.println(bean.javaPath);
    }
}

Hope it helps.

Upvotes: 1

M. Deinum
M. Deinum

Reputation: 125292

Assuming you are using java based configured.

@Bean
public static PropertySourcesPlaceholderConfigurer() {
    return new PropertySourcesPlaceholderConfigurer();
}

Then annotate a field with @Value

@Value("${port:8080}")
private int port;

This will check the System properties and environment for the given property port. When having JNDI enabled that will be checked to and when having a servlet based environment you can have it as a servlet variable as well.

The use of the PropertySourcesPlaceholderConfigurer doesn't require property files it requires PropertySources for which there are several different implementations.

If you don't want to register the PropertySourcesPlaceholderConfigurer you can revert to SpEL but that would make it a bit more complex (and ugly imho).

Upvotes: 4

fps
fps

Reputation: 34480

I haven't tried, but you could use any SpEL expression. Your code could be rewritten as:

@Value("#{systemProperties['port'] ?: 8080}")
private int port;

Note that I'm using the safe navigation operator.

Regarding PropertySourcesPalceholderConfigurer, I don't think you need one, given you have the Spring Expression Language dependency in your classpath:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-expression</artifactId>
    <version>4.2.3.RELEASE</version>
</dependency>

Upvotes: 1

Related Questions