Siena
Siena

Reputation: 777

How to convert @Propertysource file to Map?

I have my contents in .properties file. I'm loading the properties file using @PropertySource.

How do i get the contents from the properties file to map using @PropertySource Annotation?

My Property file looks like this:

a= abc
b= bcd
c= cde

In my Component, I want to read the property file and put the contents in a map.

@PropertySource("classpath:myData.properties")
public class myComponentService {

@Autowired
private Environment environment;

Map<String, String> myMap = new HashMap<String, String>(); //Property file content goes here

}  

I tried something like this, but this doesn't work.

Map<String, String> myMap= new HashMap<String, String>();
Properties myProperties = new Properties();
myProperties .putAll(myMap);

Upvotes: 2

Views: 5542

Answers (4)

Siena
Siena

Reputation: 777

so, I tried with the following two methods, they both worked:

Method 1: content of my properties file looks like this-

search.myprop.a = abc
search.myprop.b = bcd
search.myprop.c = def

In my java component:

import org.springframework.core.env.AbstractEnvironment;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.EnumerablePropertySource;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.beans.factory.annotation.Autowired;
....
@org.springframework.context.annotation.PropertySource("classpath:myproperty-file-.properties")
public class MyBaseClass {
    @Autowired
    private Environment environment;
...
Map<String, String> myMap= new HashMap<String, String>();
    for (PropertySource<?> propertySource : ((ConfigurableEnvironment) environment).getPropertySources()) {
                            if (propertySource instanceof EnumerablePropertySource) {
                                for (String key : ((EnumerablePropertySource) propertySource).getPropertyNames()) {
                                    if (key.startsWith("search")) {
                                        myMap.put(key.replace("search.myprop.", ""), propertySource.getProperty(key).toString());
                                    }
                                }
                            }
                        }

This worked perfectly as I wanted. But unnecessarily iterating through all the properties' file is the downside. The better way is using @ConfigurationProperties annotation. Reference: [https://www.baeldung.com/configuration-properties-in-spring-boot][1]

Method 2:

  1. create a configuration file.

    import java.util.Map;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.PropertySource;
    
    @Configuration
    @PropertySource("classpath:myproperty-file.properties")
    @ConfigurationProperties(prefix = "search")
    public class MypropConfigProperties {
     private Map<String, String> myprop;
    
     public Map<String, String> getMyProp() {
        return myprop;
    }
    
    public void setMyProp(Map<String, String> myprop) {
            this.myprop= myprop;
        }
    }
    
  2. In your java class

    public class MyBaseClass {
    private MypropConfigProperties mypropConfigProperties;
    
    @Autowired
    public void setMyProp(MypropConfigProperties mypropConfigProperties) {
    this.mypropConfigProperties= mypropConfigProperties;
    }
    .....
    log.info(this.mypropConfigProperties.getMyProp().toString()); // this does the final magic
    ....
    

Upvotes: 1

Abdelghani Roussi
Abdelghani Roussi

Reputation: 2817

There is a better (cleaner) way to do that by creating a Configuration Property bean as follow :

@Data
@Component
@ConfigurationProperties(prefix = "custom")
public class CustomPropertiesConfig {

    private Map<String, String> connection= new HashMap<>();

}

And then define your map in application.yml ( Yaml property file ) like this :

custom:
  connection:
    key1: value1
    key2: value2

And last but not least :

@Log4j2
@EnableConfigurationProperties
@SpringBootApplication
public class App {

    public static void main(String[] args) {
        SpringApplication.run(App.class);
    }

    @Bean
    CommandLineRunner run(CustomPropertiesConfig config){
       return (args)->{
           Map<String, String> connection = config.getConnection();
           if(connection.containsKey("key1")){
               log.info("holla");
           }
       };
    }

}

Note that :

Spring Framework provides two convenient classes that can be used to load YAML documents. The YamlPropertiesFactoryBean loads YAML as Properties and the YamlMapFactoryBean loads YAML as a Map.

And that :

YAML files cannot be loaded by using the @PropertySource annotation. So, in the case that you need to load values that way, you need to use a properties file.

So this answer is valid when you are trying to bind to a map from a yaml properties file

Upvotes: 3

Lova Chittumuri
Lova Chittumuri

Reputation: 3303

Provide this is Spring XML Configuration

<context:property-placeholder location="classpath*:database.properties,classpath*:query.properties"/>

there by you can use below annotation in application.

@Value("${propertiesName}")

Upvotes: 0

Markus Fried
Markus Fried

Reputation: 96

Hmm, not sure, what you want to do...

Usually @PropertySource is used like this:

@Configuration
@PropertySource("classpath:config.properties")
public class DbConfig {

@Value("${db.url}")
private String dbUrl;

@Value("${db.user}")
private String dbUser;

...

with "db.url" and "db.user" being specified in "config.properties".

Maybe you should look into the Environment class of Spring, too:

@Autowired
private Environment environment;

Upvotes: 0

Related Questions