20

I would like a simple, preferably annotation-based way to inject external properties into a java program, without using the spring framework (org.springframework.beans.factory.annotation.Value;)

SomeClass.java

@Value("${some.property.name}") private String somePropertyName; 

application.yml

some: property: name: someValue 

Is there a recommended way to do this in the standard library?

2
  • 1
    No, which is why Spring's functionality exists. Commented Nov 28, 2016 at 1:13
  • Since I wanted a non-spring answer, I shouldn't have included spring-* tags Commented Nov 28, 2016 at 21:46

4 Answers 4

39

I ended up using apache commons configuration:

pom.xml:

<dependency> <groupId>commons-configuration</groupId> <artifactId>commons-configuration</artifactId> <version>1.6</version> </dependency> 

src/.../PropertiesLoader.java

PropertiesConfiguration config = new PropertiesConfiguration(); config.load(PROPERTIES_FILENAME); config.getInt("someKey"); 

/src/main/resources/application.properties

someKey: 2 

I did not want to turn my library into a Spring application (I wanted @Value annotations, but no application context + @Component, extra beans, extra Spring ecosystem/baggage which doesn't make sense in my project).

Sign up to request clarification or add additional context in comments.

6 Comments

Thank you answering your question. I know this is a bad comment, but it's rare for people to come back and help others that may have the same problems. So thanks.
Are you saying you used this to read "application.yml" (emphasis on yml), OR you used this library and (reverted back) to read application.properties file?
I probably read from application.properties using this library, I don't think yml vs properties mattered to me at the time, but I don't remember.
Ok. Yeah, I like the syntax of application.yml, but the spring-baggage is too much to bear for just that component. @AnnotationEasyPeezey.
I'm surprised that this is the accepted answer with that many upvotes. The original question seemed to be asking for a pure JSR-330 way to achieve what @Value does in Spring, e.g. something like @Inject @Named("some.property.name") private String somePropertyName; (which AFAIK is not actually supported by any of the frameworks that implement JSR-330). Also, the accepted answer is not annotation-based and, moreover, does not even use dependency injection at all. In my mind, this does not answer the question at all.
|
13

Define application properties here /src/main/resources/application.properties

Define PropertiesLoader class

public class PropertiesLoader { public static Properties loadProperties() throws IOException { Properties configuration = new Properties(); InputStream inputStream = PropertiesLoader.class .getClassLoader() .getResourceAsStream("application.properties"); configuration.load(inputStream); inputStream.close(); return configuration; } } 

Inject property value in the required class like below,

 Properties conf = PropertiesLoader.loadProperties(); String property = conf.getProperty(key); 

3 Comments

This should be the accepted answer! This code works pretty well. Why including a whole library if you can accomplish it with 10 lines of self written code.
OP asks for yaml approach. This solution doesn't work for YAML files.
This class could benefit by using a singleton so it doesn't actually load every time it's called.
0

I stumbled upon this answer on google, yet i'm not satisfied.

In the end I created Environment class that uses both application properties from @Stone answer and hardcoded env variables. But Im still looking for better options, since I cannot modify ENV_VARIABLE name inside application.propeties, which is what I originally wanted.

public class EnvironmentPlainJava { public int httpsPort() { return Integer.parseInt(PropertiesLoader.loadProperties().getProperty("https.port")); } public String keyStorePath() { return System.getenv("KEY_STORE_PATH"); } } 

Comments

0

For reference, here is an idiomatic Kotlin version of the @Stone code (using ClassPathResource Spring utility class - doesn't require running Spring!):

fun loadProperties(properties: String = "application.properties"): Properties = ClassPathResource(properties).inputStream.use { inputStream -> Properties().also { it.load(inputStream) } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.