smeeb
smeeb

Reputation: 29507

Configuring and injecting Grails services

Grails 2.4.5 here. I did a grails create-service com.example.service.Simple which created a SimpleService for me, which I then modified to look like so:

class SimlpeService {
    SimpleClient simpleClient

    Buzz doSomething(String derp) {
        // ...
        Fizz fizz = simpleClient.doSomething(derp)
        // ...
        fizz.asBuzz()
    }
}

I can now "inject" controllers with SimpleService like so:

class MyController {
    SimpleService simpleService

    def index() {
        // etc...
    }
}

But how do I configure/wire SimpleService with the correct SimpleClient instance. Let's pretend SimpleClient is typically built like so:

SimpleClient simpleClient = SimpleClientBuilder
    .withURL('http://simpleclientdev.example.com/simple')
    .withAuth('luggageCombo', '12345')
    .isOptimized(true)
    .build()

Depending on what environment I'm in, I may want my SimpleClient instance to connect to simpleclientdev.example.com, simpleclientqa.example.com, or even simpleclient.example.com. Also, I may use different auth credentials, and I might/might not want it to be "optimized", etc. The point is: How do I inject the SimpleService with a SimpleClient instance?

Upvotes: 1

Views: 66

Answers (2)

Shashank Agrawal
Shashank Agrawal

Reputation: 25797

You can use the Java's PostConstruct annotation on one of your method in your service to do the stuff you want. From the docs:

The PostConstruct annotation is used on a method that needs to be executed after dependency injection is done to perform any initialization.

SimpleService.groovy

import javax.annotation.PostConstruct

class SimlpeService {

    private SimpleClient simpleClient

    def grailsApplication

    @PostConstruct
    void postConstruct() {
        def config = grailsApplication.config.client.data

        SimpleClient simpleClient = SimpleClientBuilder
            .withURL(config.url)
            .withAuth('luggageCombo', config.username)
            .isOptimized(config.optimized)
            .build()
    }

    Buzz doSomething(String derp) {
        // ...
        Fizz fizz = simpleClient.doSomething(derp)
        // ...
        fizz.asBuzz()
    }
}

So, Grails or Spring will call this method postConstruct() automatically when all the dependencies (in this case grailsApplication) for this service are resolved and any of the service method is invoked. This has been taken care that that method must invoke before you access any field member or method of the SimpleService.

Now, everything is already configured like you mentioned that you may need to call different URL with different credential, just you have to define them in your Config.groovy as:

environments {
    development {
        client {
            data {
                url = "simpleclientdev.example.com"
                username = "test"
                optimized = false
            }
        }
    }
    production {
        client {
            data {
                url = "simpleclient.example.com"
                username = "johndoe"
                optimized = true
            }
        }
    }
}

Now when you do run-app with development mode and calling simpleService.doSomething() in your example controller will automatically hit the simpleclientdev.example.com URL with test credential and when you deploy it using production environment, the same simpleService.doSomething() method will hit simpleclient.example.com with optimized set to true.

Update The key point here based on your question is that we will not be injecting different instances of SimpleService since services are singleton by default. Instead we are changing the value's associated with the service based on the environment.

Upvotes: 1

RST
RST

Reputation: 602

Sounds like you need to understand a bit more about how to leverage Spring maybe? Grails Spring Docs

You can also do things like so in your Service class

 @PostConstruct
void init() {
    //configure variables, etc here ...
    log.debug("Initialised some Service...")
}

Upvotes: 0

Related Questions