В Ratpack мы можем использовать модули Guice для организации кода для предоставления объектов в реестр. Ratpack добавляет настраиваемые модули, которые принимают дополнительный объект конфигурации. Значения из объекта конфигурации используются для создания новых объектов, предоставляемых нашему приложению. Используя Groovy DSL, у нас есть несколько способов сделать объект конфигурации доступным для настраиваемого модуля.
Давайте создадим пример настраиваемого модуля и рассмотрим различные способы придания ему объекта конфигурации. Мы создаем модуль GreetingModule
, который предоставляет Greeting
объект. Конфигурация определяется в классе GreetingConfig
.
// File: src/main/groovy/com/mrhaki/ratpack/GreetingModule.groovy
package com.mrhaki.ratpack
import com.google.inject.Provides
import groovy.transform.CompileStatic
import ratpack.guice.ConfigurableModule
@CompileStatic
class GreetingModule extends ConfigurableModule<GreetingConfig>{
@Override
protected void configure() {}
/**
* Method to create a new Greeting object with values
* from the GreetingConfig configuration object.
*/
@Provides
Greeting greeting(final GreetingConfig config) {
new Greeting(message: "${config.salutation}, ${config.message}")
}
}
// File: src/main/groovy/com/mrhaki/ratpack/GreetingConfig.groovy
package com.mrhaki.ratpack
import groovy.transform.CompileStatic
/**
* Configuration properties for creating
* a {@link Greeting} object using the
* configurable module {@link GreetingModule}.
*/
@CompileStatic
class GreetingConfig {
String message
String salutation
}
// File: src/main/groovy/com/mrhaki/ratpack/Greeting.groovy
package com.mrhaki.ratpack
import groovy.transform.CompileStatic
/**
* Simple class with a greeting message.
* The {@link GreetingModule} module creates
* an instance of this class.
*/
@CompileStatic
class Greeting {
String message
}
У нас есть наш настраиваемый модуль и вспомогательные классы. Теперь мы определяем конфигурацию и модуль в bindings
блоке нашего приложения Ratpack Groovy. Мы используем ConfigData
класс для установки свойств конфигурации, которые мы позже привязываем к GreetingConfig
объекту. С помощью ConfigData
мы можем определить свойства конфигурации из разных источников, таких как файлы в формате свойств Yaml, JSON или Java. В нашем примере мы просто определяем их, используя Map
. В первом примере мы используем module
метод с Closure
аргументом для настройки GreetingModule
// File: src/ratpack/Ratpack.groovy
import com.mrhaki.ratpack.Greeting
import com.mrhaki.ratpack.GreetingConfig
import com.mrhaki.ratpack.GreetingModule
import ratpack.config.ConfigData
import ratpack.config.ConfigDataBuilder
import static ratpack.groovy.Groovy.ratpack
ratpack {
bindings {
final ConfigData configData = ConfigData.of { ConfigDataBuilder builder ->
builder.props(
['greeting.salutation': 'Hi',
'greeting.message' : 'how are you doing?'])
// We can also use external files,
// system properties and environment
// variables to set configuration properties
// inside this block.
builder.build()
}
// The module methods allows a Closure argument to
// set values for the supported configuration class.
module GreetingModule, { GreetingConfig config ->
config.salutation = configData.get('/greeting/salutation', String)
config.message = configData.get('/greeting/message', String)
}
}
handlers {
// Simple handler using the created Greeting object.
get { Greeting greeting ->
render greeting.message
}
}
}
В следующем примере мы создаем экземпляр GreetingConfig
использования bindInstance
метода. Он GreetingModule
подберет этот экземпляр и будет использовать его автоматически:
// File: src/ratpack/Ratpack.groovy
import com.mrhaki.ratpack.Greeting
import com.mrhaki.ratpack.GreetingConfig
import com.mrhaki.ratpack.GreetingModule
import ratpack.config.ConfigData
import ratpack.config.ConfigDataBuilder
import static ratpack.groovy.Groovy.ratpack
ratpack {
bindings {
final ConfigData configData = ConfigData.of { ConfigDataBuilder builder ->
builder.props(
['greeting.salutation': 'Hi',
'greeting.message' : 'how are you doing?'])
// We can also use external files,
// system properties and environment
// variables to set configuration properties
// inside this block.
builder.build()
}
// First create an instance of the GreetingConfig class.
bindInstance GreetingConfig, configData.get('/greeting', GreetingConfig)
// With the module method we use the GreetingModule and
// because there is a GreetingConfig instance available
// it is used to configure the module.
module GreetingModule
}
handlers {
// Simple handler using the created Greeting object.
get { Greeting greeting ->
render greeting.message
}
}
}
Наконец, мы можем использовать moduleConfig
метод. Этот метод принимает объект конфигурации непосредственно в качестве аргумента. Таким образом, мы можем использовать экземпляр в GreetingConfig
качестве аргумента метода. Мы также можем объединить его с Closure
аргументом для переопределения свойств конфигурации:
// File: src/ratpack/Ratpack.groovy
import com.mrhaki.ratpack.Greeting
import com.mrhaki.ratpack.GreetingConfig
import com.mrhaki.ratpack.GreetingModule
import ratpack.config.ConfigData
import ratpack.config.ConfigDataBuilder
import static ratpack.groovy.Groovy.ratpack
ratpack {
bindings {
final ConfigData configData = ConfigData.of { ConfigDataBuilder builder ->
builder.props(
['greeting.salutation': 'Hi',
'greeting.message' : 'how are you doing?'])
// We can also use external files,
// system properties and environment
// variables to set configuration properties
// inside this block.
builder.build()
}
// With the moduleConfig method we can pass an instance
// of GreetingConfig directly.
moduleConfig GreetingModule, configData.get('/greeting', GreetingConfig)
// Or we can even combine it with a Closure argument to override a
// configuration property.
//moduleConfig(
// GreetingModule,
// configData.get('/greeting', GreetingConfig)) { GreetingConfig config ->
// config.message = 'Ratpack rocks!'
//}
}
handlers {
// Simple handler using the created Greeting object.
get { Greeting greeting ->
render greeting.message
}
}
}