////
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
////

Configuration in Grails is generally split across 2 areas: build configuration and runtime configuration.

Build configuration is generally done via Gradle and the `build.gradle` file. Runtime configuration is by default specified in YAML in the `grails-app/conf/application.yml` file.

If you prefer to use Grails 2.0-style Groovy configuration then it is possible to specify configuration using Groovy's http://docs.groovy-lang.org/latest/html/documentation/#_configslurper[ConfigSlurper] syntax. Two Groovy configuration files are available: `grails-app/conf/application.groovy` and `grails-app/conf/runtime.groovy`:

. Use `application.groovy` for configuration that doesn't depend on application classes
. Use `runtime.groovy` for configuration that does depend on application classes

[NOTE]
====
This separation is necessary because configuration values defined in `application.groovy` are available to the Grails CLI, which needs to be able to load `application.groovy` before the application has been compiled. References to application classes in `application.groovy` will cause an exception when these commands are executed by the CLI:
----
Error occurred running Grails CLI: 
startup failed:script14738267015581837265078.groovy: 13: unable to resolve class com.foo.Bar
----
====

For Groovy configuration the following variables are available to the configuration script:

[format="csv", options="header", separator="|"]
|===

*Variable*|*Description*
userHome|Location of the home directory for the account that is running the Grails application.
appName|The application name as it appears in build.gradle.
appVersion|The application version as it appears in build.gradle.
|===

For example:

[source,groovy]
----
my.tmp.dir = "${userHome}/.grails/tmp"
----


=== Accessing Configuration with GrailsApplication

If you want to read runtime configuration settings, i.e. those defined in `application.yml`, use the {apiDocs}grails/core/GrailsApplication.html[grailsApplication] object, which is available as a variable in controllers and tag libraries:

[source,groovy]
----
class MyController {
    def hello() {
        def recipient = grailsApplication.config.getProperty('foo.bar.hello')

        render "Hello ${recipient}"
    }
}
----

The `config` property of the `grailsApplication` object is an instance of the {apiDocs}grails/config/Config.html[Config] interface and provides a number of useful methods to read the configuration of the application.

In particular, the `getProperty` method (seen above) is useful for efficiently retrieving configuration properties, while specifying the property type (the default type is String) and/or providing a default fallback value.

[source,groovy]
----
class MyController {

    def hello(Recipient recipient) {
        //Retrieve Integer property 'foo.bar.max.hellos', otherwise use value of 5
        def max = grailsApplication.config.getProperty('foo.bar.max.hellos', Integer, 5)

        //Retrieve property 'foo.bar.greeting' without specifying type (default is String), otherwise use value "Hello"
        def greeting = grailsApplication.config.getProperty('foo.bar.greeting', "Hello")

        def message = (recipient.receivedHelloCount >= max) ?
          "Sorry, you've been greeted the max number of times" :  "${greeting}, ${recipient}"
        }

        render message
    }
}
----


Notice that the `Config` instance is a merged configuration based on Spring's {springapi}org/springframework/context/annotation/PropertySource.html[PropertySource] concept and reads configuration from the environment, system properties and the local application configuration merging them into a single object.

`GrailsApplication` can be easily injected into services and other Grails artifacts:

[source,groovy]
----
import grails.core.*

class MyService {
    GrailsApplication grailsApplication

    String greeting() {
        def recipient = grailsApplication.config.getProperty('foo.bar.hello')
        return "Hello ${recipient}"
    }
}
----

=== GrailsConfigurationAware Interface

Accessing configuration dynamically at runtime can have a small effect on application performance. An alternative approach is to implement the {apiDocs}grails/core/support/GrailsConfigurationAware.html[GrailsConfigurationAware] interface, which provides a `setConfiguration` method that accepts the application configuration as a parameter when the class is initialized. You can then assign relevant configuration properties to instance properties on the class for later usage.

The `Config` instance has the same properties and usage as the injected `GrailsApplication` config object. Here is the service class from the previous example, using `GrailsConfigurationAware` instead of injecting `GrailsApplication`:

[source,groovy]
----
import grails.core.support.GrailsConfigurationAware

class MyService implements GrailsConfigurationAware {

    String recipient

    String greeting() {
        return "Hello ${recipient}"
    }

    void setConfiguration(Config config) {
        recipient = config.getProperty('foo.bar.hello')
    }

}
----

=== Spring Value Annotation

You can use Spring's {springapi}org/springframework/beans/factory/annotation/Value.html[Value] annotation to inject configuration values:

[source,groovy]
----
import org.springframework.beans.factory.annotation.*

class MyController {
    @Value('${foo.bar.hello}')
    String recipient

    def hello() {
        render "Hello ${recipient}"
    }
}
----

NOTE: In Groovy code you must use single quotes around the string for the value of the `Value` annotation otherwise it is interpreted as a GString not a Spring expression.

As you can see, when accessing configuration settings you use the same dot notation as when you define them.
