I've spoken about my approach to this elsewhere, apologies if you've
already come across this. I use Dropwizard which has a concept of Managed
classes which get started and stopped by dropwizard. Though, you could do
something like this yourself too if you are opposed to dropwizard.

My abstract module looks like this (please excuse the Scala; it simplifies
some of the verbosity otherwise):

trait DropwizardModule[B <: Binder] extends Module {
  self: InternalModule[B] =>

  private[this] var injectorProvider: Provider[Injector] = null

  final def configure() {
    binderAccess.requireExplicitBindings()
    injectorProvider = getProvider[Injector]
    doConfigure()
  }

  protected[this] def injector = injectorProvider.get()

  def doConfigure()
  def install(env: Environment)
}

abstract class DropwizardPublicModule extends ScalaModule with
DropwizardModule[Binder]

abstract class DropwizardPrivateModule extends ScalaPrivateModule with
DropwizardModule[PrivateBinder]


Note how I always create a reference to a provider of the module's
injector; this makes working with PrivateModule's a breeze as you will
always get the local module and you don't need to expose things that simply
get registered with dropwizard/jersey (or started/stopped by your code).

Then a very simple Module might look like this:

class TestModule extends DropwizardPrivateModule {
  def doConfigure() {
    bind[TestResource].asEagerSingleton()
    bind[TestService].asEagerSingleton()
  }

  def install(env: Environment) {
    env.addResource(injector.instance[TestResource])
    env.manage(injector.instance[TestService])
  }
}

Note: You could easily have your install method pass in an array list of
Managed objects if you wanted to start / stop all on your own (and not use
dropwizard).

And then in my main Service's run method I have code that looks like this:

  def run(cfg: TestApplicationConfiguration, env: Environment) {
    val modules: List[DropwizardModule[_]] = List(
      new TestModule
    )

    val injector = Guice.createInjector(modules: _*)
    modules.foreach(_.install(env))
  }


I keep reusing this approach over and over and have really found it to work
extremely well. It allows you to delegate more responsibilities to each
module; In addition to configuring some specific sub-graph of your
application it's now responsible for starting, stopping, installing,
registering whatever it needs in your applications framework. Most
importantly, it enables a bit more freedom when you need to mix-n-match
modules more freely without the hassle of dealing with updating your main
method to comment/uncomment start()/stop() calls.

This is more or less similar to the multi-binder approach but also works
across private modules and is more flexible for dropwizard (and other
frameworks where you might want to do more than just start/stop instances
in your injector).

Anyways, that's my food for thought.
Nate

On Thu, Oct 2, 2014 at 2:04 PM, Sam Berlin <[email protected]> wrote:

> One decent approach is to use Guava's Service & ServiceManager
> <https://code.google.com/p/guava-libraries/wiki/ServiceExplained>, then
> bind your services using a multibinder and @Provides a ServiceManager
> constructed with the result of that multibinder.  Then you can just
> start/stop the ServiceManager, which will start/stop each service.
>
> sam
>
> On Thu, Oct 2, 2014 at 1:53 PM, Kevin Burton <[email protected]> wrote:
>
>> I have a bunch of services that need to be started and stopped.  ActiveMQ
>> , Cassandra, Jetty, etc...
>>
>> They use files, start ports, etc.
>>
>> I imagine the best strategy to just have a leif Node service just start
>> its dependencies in its start() method.. then stop them.
>>
>> So the could would look something like the following...
>>
>> but it would be nice if the start/stop methods were auto-wrapped ...
>>
>> This way on shutdown all threads and resources can be properly released.
>>
>> This is also helpful in testing so that if you have an impl that creates
>> threads they can be released.
>>
>> public class Main {
>>
>>     public static void main( String... args ) {
>>
>>       MyService service = injector.getInstance( MyService.class )
>>
>>     }
>>
>> }
>>
>> public class MyService {
>>
>>     @Inject
>>     MyService( WebserverService webserverService ) {
>>         ...
>>     }
>>
>>     public void start() {
>>         webserverService.start();
>>     }
>>
>>     public void stop() {
>>         webserverService.stop();
>>     }
>>
>> }
>>
>>
>> public class Webserver {
>>
>>     @Inject
>>     MyService( CassandraService cassandraService ) {
>>         ...
>>     }
>>
>>     public void start() {
>>         cassandraService.start();
>>     }
>>
>>     public void stop() {
>>         cassandraService.stop();
>>     }
>>
>> }
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "google-guice" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to [email protected].
>> To post to this group, send email to [email protected].
>> Visit this group at http://groups.google.com/group/google-guice.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/google-guice/f5e11810-1aa3-4a4c-882a-ddc84d258e57%40googlegroups.com
>> <https://groups.google.com/d/msgid/google-guice/f5e11810-1aa3-4a4c-882a-ddc84d258e57%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>  --
> You received this message because you are subscribed to the Google Groups
> "google-guice" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at http://groups.google.com/group/google-guice.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/google-guice/CAJEBNUdjyiTBC9B6RKVzip_CJgMOSqnc7eVDBTT6cHZ2AVyjxw%40mail.gmail.com
> <https://groups.google.com/d/msgid/google-guice/CAJEBNUdjyiTBC9B6RKVzip_CJgMOSqnc7eVDBTT6cHZ2AVyjxw%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
>
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"google-guice" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/google-guice.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/google-guice/CAHNex997Gg0q3qMW6Mt6Wybq51dAnUQj9%2BQfaDPuwP39fEDcCg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to