Last updated by admin
5 years ago
Unified configuration refactor
Objective
There is a requirement for provided pre-init configuration settings that can be picked up by plugins during load time. There are also a number of other disparate configuration points in Grails 0.5.5 that should be rationalized before the 1.0 release:- DataSources - are classes needlessly, and hence require a file per environment
- Bootstrap - currently does not provide per-environment support out of the box, and does not provide a means to configure spring beans or metaclasses etc
- resources.xml - ugly XML that should be handled akin to doWithSpring in plugins, as per previous comment on Bootstrap
Proposal
The crux of it is quite simple:- Favour a environment-aware DSLs over per-environment class files.
- Use script files instead of classes where performance will not be an issue (scripts perform poorly in a multithreaded environment so are unsuitable for supply closures to EMCs for example)
- Supply doWithXXX functionality for application bootstrapping in the same way it is done for plugins
Property configuration file
Here properties are defined that are accessible to plugins and the application, and spring beans, based on current environment.// Top-level assignments apply to all environments grails.webflow.stateless = trueenv { development { resources.URL = "http://localhost:8088" smtp { mail.host = 'smtp.myisp.com' mail.auth.user = 'server' } } production { resources.URL = "http://localhost:80/resources" smtp.mail.host = 'localhost' } }
Datasource configuration file
Replacing XXXXDataSource.groovy we have single file DataSource.groovy:// Applies to all envs pooling = trueenv { dev { dbCreate = "create-drop" // one of 'create', 'create-drop','update' url = "jdbc:hsqldb:mem:devDB" driverClassName = "org.hsqldb.jdbcDriver" username = "sa" password = "" } production { dbCreate = "update" // one of 'create', 'create-drop','update' url = "jdbc:mysql://localhost/appDB" driverClassName = "com.mysql.jdbc.Driver" username = "admin" password = "secret" } }
Bootstrap
ApplicationBootstrap will remain a class, as it may affect metaclasses and hence performance is a consideration.Q: How to factor environments in here? Should 'env' not be used here too, for consistency?class ApplicationBootstrap {
def init = { ServletContext sc ->
dev {
…
}
production {
…
}
}
def destroy = {
}
def doWithSpring = {
dev {
…
}
production {
…
}
}
def doWithApplicationContext = {
}
}Two-phase configuration
Configuration will occur in two phases, first the config will be built-up into an evaluatable "config" object which can be inspected by plugins:if(!config.dataSource?.driverClassName) // configure default driver