While working on converting a Grails application to a SpringBoot based application, I was trying to understand how the auto configurations and custom configurations work under the hood. Just like CoC of Groovy/Grails, there seems to be a lot of hide-and-seek going on under the Spring boot hood. Admittedly its been a while for me with good ol’ raw Spring, so the many different ways of skinning the configuration felt a bit overwhelming. I counted several concepts around configurations – application.properties, application.yaml, PropertySource, PropertyPlaceHolder, @Value, @EnableConfiguration, @EnableConfigurationProperties, @EnableAutoConfiguration, @Configuration, @ConfigurationProperties, pre-defined property name prefixes, creating classes specifically for holding configuration values – so much information just for accessing key-value pairs? Compare to Grails – one Config.groovy (or multiple externalized) and a simple grailsApplication injection takes care of making configuration available anywhere. When I read Spring Boot support for Groovy, I somehow assumed that support for a groovy config is automatically enabled.
My Grails application already had a groovy config, and I was not in a mood to convert them to .properties or .yaml. Groovy configs are DSLs in essence – it provides many advantages over the traditional properties file: key=value (like .properties), a structured format like .yaml – sans the indent-erasure-phobia, type-enriched config values like list/map etc, functions via closures and more.
So, here is a very simple way to expose the groovy config to your Spring Boot apps:
Create a Config.groovy in the same folder as the ConfigProperties class.
/** Config.groovy **/ //simple key-value spring.boot.guide = 'https://github.com/spring-guides?page=1' //formatted structure google { searchurl = 'http://www.google.com' apiKey = '1234' } /** ConfigProperties.groovy **/ import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration @Configuration class ConfigProperties { @Bean(name="configObject") ConfigObject configObject() { return new ConfigSlurper().parse(Config) } } /** HelloController.groovy **/ import ConfigProperties import org.springframework.beans.factory.annotation.Autowired import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController @RestController class HelloController { @Autowired ConfigObject configObject @RequestMapping("/") String home() { return "Hello World! " + configObject.spring.boot.guide } } /** Application.groovy **/ @EnableAutoConfiguration @ComponentScan class Application { static void main(String[] args) { Object[] sources = [Application.class, ConfigProperties.class] SpringApplication.run(sources, args) } }
Note: @Bean returns must be typed. Habitually, I wrote def configObject() { return new ConfigSlurper().parse(Config) } and the @Autowired did not wire it up.
Does not work. What is Config here:
@Bean(name=”configObject”)
ConfigObject configObject() {
return new ConfigSlurper().parse(Config)
}
LikeLike
@Vladimir, Config is the Config.groovy file that should be available in classpath.
LikeLike