13.3 Dependency Injection and Services 4.0.10

(Quick Reference) # 13.3 Dependency Injection and Services Version: 4.0.10 ## 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 called `BookService`, if you define a property called `bookService` in a controller as follows:
    class BookController {
        def bookService
        ...
    }
In this case, the Spring container will automatically inject an instance of that service based on its configured scope. All dependency injection is done by name. You can also specify the type as follows:
    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 the `BookService` class would map to a property named `bookService`.
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 the `JDBCHelperService` class would be `JDBCHelperService`, not `jDBCHelperService` or `jdbcHelperService`. 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.
Be careful when injecting the non-default datasources. For example, using this config:
    dataSources:
        dataSource:
            pooled: true
            jmxExport: true
            .....
        secondary:
            pooled: true
            jmxExport: true
            .....
You can inject the primary `dataSource` like you would expect:
    class BookSqlService {

          def dataSource
    }
But to inject the `secondary` datasource, you have to use Spring’s `Autowired` injection or `resources.groovy`.
    class BookSqlSecondaryService {

      @Autowired
      @Qualifier('dataSource_secondary')
      def dataSource2
    }
#### Dependency Injection and Services You can inject services in other services with the same technique. If you had an `AuthorService` 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)
        }
    }
| Since Grails 3.2.8 this is not enabled by default. If you want to enable it again, take a look at Spring Autowiring of Domain Instance
#### 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 named `com.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. | Quick Reference (hide)