Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring-Boot multi module project load property-file

I have a Spring-Boot-Application as a multimodule-Project in maven. The structure is as follows:

Parent-Project
|--MainApplication
|--Module1
|--ModuleN

In the MainApplication project there is the main() method class annotated with @SpringBootApplication and so on. This project has, as always, an application.properties file which is loaded automatically. So I can access the values with the @Value annotation

@Value("${myapp.api-key}")
private String apiKey;

Within my Module1 I want to use a properties file as well (called module1.properties), where the modules configuration is stored. This File will only be accessed and used in the module. But I cannot get it loaded. I tried it with @Configuration and @PropertySource but no luck.

@Configuration
@PropertySource(value = "classpath:module1.properties")
public class ConfigClass {

How can I load a properties file with Spring-Boot and access the values easily? Could not find a valid solution.

My Configuration

@Configuration
@PropertySource(value = "classpath:tmdb.properties")
public class TMDbConfig {

    @Value("${moviedb.tmdb.api-key}")
    private String apiKey;

    public String getApiKey() {
        return apiKey;
    }

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

Calling the Config

@Component
public class TMDbWarper {

@Autowired
private TMDbConfig tmdbConfig;

private TmdbApi tmdbApi;

public TMDbWarper(){
    tmdbApi = new TmdbApi(tmdbConfig.getApiKey());
}

I'm getting an NullPointerException in the constructor when I autowire the warper.

like image 777
Daniel Avatar asked Oct 17 '17 06:10

Daniel


People also ask

How do I load a properties file in spring boot?

properties in default location. Spring Boot loads the application. properties file automatically from the project classpath. All you have to do is to create a new file under the src/main/resources directory.

How import multiple properties in spring boot?

To add different files you can use the spring. config. location properties which takes a comma separated list of property files or file location (directories). The one above will add a directory which will be consulted for application.

Can spring boot have multiple properties files?

properties” property file, as it was automatically built inside the Spring boot application when the project is initially created. We can create and maintain multiple property files within “Resources” module, where we will be able to define different types of property values in different files.


2 Answers

For field injection:

Fields are injected right after construction of a bean, before any config methods are invoked. Such a config field does not have to be public. Refer Autowired annotation for complete usage. Use constructor injection in this case like below:

@Component
public class TMDbWarper {

    private TMDbConfig tmdbConfig;

    private TmdbApi tmdbApi;

    @Autowired
    public TMDbWarper(final TMDbConfig tmdbConfig){
            this.tmdbConfig = tmdbConfig;
            tmdbApi = new TmdbApi(tmdbConfig.getApiKey());
    }

(or)

Use @PostConstruct to initialise like below:

@Component
public class TMDbWarper {

    @Autowired
    private TMDbConfig tmdbConfig;

    private TmdbApi tmdbApi;

    @PostConstruct
    public void init() {
        // any initialisation method
        tmdbConfig.getConfig();
    }
like image 190
Subash J Avatar answered Oct 15 '22 05:10

Subash J


Autowiring is performed just after the creation of the object(after calling the constructor via reflection). So NullPointerException is expected in your constructor as tmdbConfig field would be null during invocation of constructor

You may fix this by using the @PostConstruct callback method as shown below:

@Component
public class TMDbWarper {

    @Autowired
    private TMDbConfig tmdbConfig;

    private TmdbApi tmdbApi;

    public TMDbWarper() {

    }

    @PostConstruct
    public void init() {
        tmdbApi = new TmdbApi(tmdbConfig.getApiKey());
    }

    public TmdbApi getTmdbApi() {
        return this.tmdbApi;
    }
}

Rest of your configuration seems correct to me.

Hope this helps.

like image 44
skadya Avatar answered Oct 15 '22 04:10

skadya