Fork me on GitHub

Dispose

Let's start on defining an object type that requires dependency injection and that a callback has to be invoked once application will be shutdown:

import org.nnsoft.guice.lifegycle.Dispose;

@Singleton // not necessary, but let's add some spice
public class MyServiceImpl
{

    @Inject
    private Dependency dependency;

    // setter omitted for simplicity

    @Dispose
    public void tearDown()
    {
        ...
    }

}

All users have to do, is adding the DisposeModule when creating the Injector:

import static com.google.inject.Guice.createInjector;

import org.nnsoft.guice.lifegycle.DisposeModule;

...

Injector injector = createInjector( new DisposeModule(), ... );

Then, require the org.nnsoft.guice.lifegycle.Disposer injection to shutdown the application:

import org.nnsoft.guice.lifegycle.Disposer;

...

Runtime.getRuntime().addShutdownHook( new Thread()
{

    public void run()
    {
        injector.getInstance( Disposer.class ).dispose();
    }

} );

Of course, same concept can be applied to any listener javax.servlet.ServletContextListener:

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public final class ContextListener
   implements ServletContextListener
{

    private Injector injector;

    public void contextDestroyed( ServletContextEvent event )
    {
        injector.getInstance( Disposer.class ).dispose();
    }

    public void contextInitialized( ServletContextEvent event )
    {
        ...
    }

}

Dispose Handling

Users interested on tracking/logging/... objects dispose progresses, can register a org.nnsoft.guice.lifegycle.DisposeHandler, which has the following methods signatures:

public interface DisposeHandler
{

    <I> void onSuccess( I injectee );

    <I, E extends Throwable> void onError( I injectee, E error );

}

A DisposeHandler instance can be passed to Disposer#dispose() method:

injector.getInstance( Disposer.class ).dispose( new DisposeHandler
{

    public <I> void onSuccess( I injectee )
    {
        logger.info( "Object {} successfully released resources", injectee );
    }

    public <I, E extends Throwable> void onError( I injectee, E error )
    {
        logger.error( "Impossible to released resources of " + injectee, error );
    }

} );

Customization

The DisposeModule module supports dynamic definition of the annotation has to be handled; let's replace the org.nnsoft.guice.lifegycle.Dispose with the javax.annotation.PreDestroy:

import javax.annotation.PreDestroy;

@Singleton // not necessary, but let's add some spice
public class MyServiceImpl
{

    @Inject
    private Dependency dependency;

    // setter omitted for simplicity

    @PreDestroy
    public void tearDown()
    {
        ...
    }

}

then, create the Injector:

import static com.google.inject.Guice.createInjector;

import javax.annotation.PreDestroy;
import org.nnsoft.guice.lifegycle.AfterInjectionModule;

...

Injector injector = createInjector( new DisposeModule( PreDestroy.class, Matchers.any() ), ... );