Ashish
Ashish

Reputation: 341

Load custom properties file in Spring Boot MVC Main

I have created a myApp.properties in resources folder location and mentioned the server.port in this file.

myApp.properties

myApp.server.port=8020

Now I want to read load this property into my application. But I have to read this before I actually a server.

Here I am trying to do like this

@SpringBootApplication
@ComponentScan(basePackages = {"com.myorg.myapp" })
@EnableConfigurationProperties
@PropertySource("classpath:myApp.properties")
@Component
public class MyAppApplication {

    @Value("${myApp.server.port}")
    private static String serverPort;

    public static void main(String[] args) throws Exception{
        try {

            SpringApplication appCtxt = new SpringApplication(MyAppApplication.class);
            appCtxt.setDefaultProperties(Collections
                    .singletonMap("server.port", serverPort));

            appCtxt.run(args);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

But serverPort is coming as null.

I also tried to create a separate Config file like this but it can't be accessed in static main

@Configuration
@PropertySource("myApp.properties")
@ConfigurationProperties

public class MyAppConfig {

    @Value("${myApp.server.port}")
    private String serverPort;

    /**
     * @return the serverPort
     */
    public String getServerPort() {
        return serverPort;
    }

}

Any suggestion would be helpful.

Upvotes: 0

Views: 12299

Answers (2)

Mark Bramnik
Mark Bramnik

Reputation: 42441

Spring boot injects properties during the initialization of the application context. This happens (gets triggered) in the line:

appCtxt.run(args);

But you try to access the property before this line - that why it doesn't work.

So bottom line, using "@Value" in the main method doesn't work and it shouldn't.

Now from the code snippet, it looks like you could merely follow the "standards" of spring boot and create the file application.properties with:

server.port=1234

The process of starting the embedded web server in spring boot honors this property and bottom line it will have the same effect and Tomcat will be started on port 1234

Update 1

Based on OP's comment:

So, how can I have multiple application.properties.

In the Spring Boot's documentation it is written that application.properties are resolved from the classpath. So you can try the following assuming you have different modules A,B,C and web app D:

  • Create src/main/resources/application.properties inside each of 4 modules and pack everything together. The configuration values will be merged (hopefully they won't clash)

  • If you insist on naming properties A.properties, B.properties and C.properties for each of non-web modules, you can do the following (I'll show for module A, but B and C can do the same).

@Configuration
@PropertySource("classpath:A.properties")
public class AConfiguration {

}

Create in Module A: src/main/resources/A.properties

If you need to load the AConfiguration automatically - make the module A starter (using autoconfig feature of spring-boot):

Create src/resources/META-INF/spring.factories file with the following content:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
<package_of_AConfiguration>.AConfiguration

Also this has been the requirement to separate C from entire bundle where it might run as bundle for some and as a separate for some others

Although I haven't totally understood the requirement, but you can use @ConditionalOnProperty for configuration CConfiguration (that will be created just like AConfiguration.java in my previous example) but this times for module C.

If the conditional is met, configuration will run and load some beans / load its own properties or whatever. All in all conditionals (and in particular Profiles in spring) can help to reach the desired flexibility.

Upvotes: 1

varman
varman

Reputation: 8894

By default, the application.properties file can be used to store property pairs, though you can also define any number of additional property files.

If you save myApp.server.port=8020 in application.properties, it will work fine.

To register a custome property file, you can annotate a @Configuration class with the additional @PropertySource annotation:

@Configuration
@PropertySource("classpath:custom.properties")
@PropertySource("classpath:another.properties")
public class ConfigClass {
   // Configuration
}

make sure, your class path is correct.

Upvotes: 0

Related Questions