13.3 Dependency Injection and Services - Reference Documentation
Authors: Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith, Lari Hotari
Version: 3.1.9
13.3 Dependency Injection and Services
Dependency Injection Basics
A key aspect of Grails services is the ability to use Spring Framework's dependency injection features. Grails supports "dependency injection by convention". In other words, you can use the property name representation of the class name of a service to automatically inject them into controllers, tag libraries, and so on.As an example, given a service calledBookService, if you define a property called bookService in a controller as follows:class BookController {
def bookService
…
}class AuthorService {
BookService bookService
}NOTE: Normally the property name is generated by lower casing the first letter of the type. For example, an instance of theBookServiceclass would map to a property namedbookService.To be consistent with standard JavaBean conventions, if the first 2 letters of the class name are upper case, the property name is the same as the class name. For example, the property name of theJDBCHelperServiceclass would beJDBCHelperService, notjDBCHelperServiceorjdbcHelperService.See section 8.8 of the JavaBean specification for more information on de-capitalization rules.
Only the top level object is subjected to injection as traversing all nested objects to perform injection would be a performance issue.
Dependency Injection and Services
You can inject services in other services with the same technique. If you had anAuthorService that needed to use the BookService, declaring the AuthorService as follows would allow that:class AuthorService {
def bookService
}Dependency Injection and Domain Classes / Tag Libraries
You can even inject services into domain classes and tag libraries, which can aid in the development of rich domain models and views:class Book {
…
def bookService def buyBook() {
bookService.buyBook(this)
}
}Service Bean Names
The default bean name which is associated with a service can be problematic if there are multiple services with the same name defined in different packages. For example consider the situation where an application defines a service class namedcom.demo.ReportingService and the application uses a plugin named ReportingUtilities and that plugin provides a service class named com.reporting.util.ReportingService. The default bean name for each of those would be reportingService so they would conflict with each other. Grails manages this by changing the default bean name for services provided by plugins by prefixing the bean name with the plugin name. In the scenario described above the reportingService bean would be an instance of the com.demo.ReportingService class defined in the application and the reportingUtilitiesReportingService bean would be an instance of the com.reporting.util.ReportingService class provided by the ReportingUtilities plugin. For all service beans provided by plugins, if there are no other services with the same name within the application or other plugins in the application then a bean alias will be created which does not include the plugin name and that alias points to the bean referred to by the name that does include the plugin name prefix. For example, if the ReportingUtilities plugin provides a service named com.reporting.util.AuthorService and there is no other AuthorService in the application or in any of the plugins that the application is using then there will be a bean named reportingUtilitiesAuthorService which is an instance of this com.reporting.util.AuthorService class and there will be a bean alias defined in the context named authorService which points to that same bean.
