0

I have Spring Boot Application, with application.properties that look like so

com.mycompany.schedule.test=welcome
com.mycompany.schedule.test2=hi there

I would like these to be deserialized into a Map

I have tried the following, and other variants, but it doesnt seem to work

  private Map<String, String> schedules;

  @Value("${com.mycompany.schedule}")
  public void setSchedules(Map<String, String> values) {
    this.schedules = values;
  }
Brad Parks
  • 66,836
  • 64
  • 257
  • 336
  • 1
    Does this answer your question? [Spring Boot - inject map from application.yml](https://stackoverflow.com/questions/24917194/spring-boot-inject-map-from-application-yml) – Rumid Nov 06 '19 at 13:05
  • Thanks for the feedback, but none of those approaches worked, surprisingly. – Brad Parks Nov 06 '19 at 14:46

1 Answers1

0

Option 1:

In your configuration class read the application.properties file using @PropertySource annotation as below.

MyAppConfiguration.java

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

@Configuration
@PropertySource(name = "customPropertySource", value = "classpath:application.properties")
public class MyAppConfiguration {

}

Then in your POJO (or any other spring component), you can Environment class to get the properties.

MyPojo.java

import java.util.Map;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.io.support.ResourcePropertySource;
import org.springframework.stereotype.Component;

@Component
public class MyPojo {

    @Autowired
    private ConfigurableEnvironment env;

    private Map<String, Object> schedules;

    @PostConstruct
    public void properties() {
        Object propSourceObj = env.getPropertySources().get("customPropertySource");
        if (propSourceObj instanceof ResourcePropertySource) {
            ResourcePropertySource propSource = (ResourcePropertySource) propSourceObj;
            setSchedules(propSource.getSource());
        }
        System.out.println("Schedules: " + getSchedules());

    }

    public Map<String, Object> getSchedules() {
        return schedules;
    }

    public void setSchedules(Map<String, Object> schedules) {
        this.schedules = schedules;
    }

}

Please note that, with this option you are reading the application.properties file twice. If you are ok with it, you can choose option 1. Otherwise, you can choose option 2.

Option 2:

MyAppConfiguration.java

import org.springframework.context.annotation.Configuration;

@Configuration
public class MyAppConfiguration {

}

MyPojo.java

import java.util.Map;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.env.OriginTrackedMapPropertySource;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.stereotype.Component;

@Component
public class MyPojo {

    @Autowired
    private ConfigurableEnvironment env;

    private Map<String, Object> schedules;

    @PostConstruct
    public void properties() {
        Object propSourceObj = env.getPropertySources().get("applicationConfig: [classpath:/application.properties]");
        if (propSourceObj instanceof OriginTrackedMapPropertySource) {
            OriginTrackedMapPropertySource propSource = (OriginTrackedMapPropertySource) propSourceObj;
            setSchedules(propSource.getSource());
        }
        System.out.println("Schedules: " + getSchedules());

    }

    public Map<String, Object> getSchedules() {
        return schedules;
    }

    public void setSchedules(Map<String, Object> schedules) {
        this.schedules = schedules;
    }

}

Edit:

Sorry, Earlier I misunderstood your question. If you know the property prefix, then you can use @ConfigurationProperties as shown below. The above options are to read all properties without knowing the property prefix.

MyAppConfiguration.java

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyAppConfiguration {

    @Autowired
    private MyCompanyConfigurationProperties myCompanyConfProps;

    @PostConstruct
    public void testProperteis() {
        System.out.println("My Properties: " + myCompanyConfProps.getSchedule());
    }

}

MyCompanyConfigurationProperties.java

import java.util.HashMap;
import java.util.Map;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "com.mycompany")
public class MyCompanyConfigurationProperties {

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

    public Map<String, String> getSchedule() {
        return schedule;
    }

    public void setSchedule(Map<String, String> schedule) {
        this.schedule = schedule;
    }

}
Ramu
  • 641
  • 6
  • 9