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 javax.annotation.PreDestroy;
import javax.inject.Singleton;
@Singleton // not necessary, but let's add some spice
public class MyServiceImpl
{
@Inject
private Dependency dependency;
// setter omitted for simplicity
@PreDestroy
public void tearDown()
{
...
}
}All users have to do, is adding the PreDestroyModule when creating the Injector:
import static com.google.inject.Guice.createInjector; import org.apache.onami.lifecycle.jsr250.PreDestroyModule; ... Injector injector = createInjector( new PreDestroyModule(), ... );
Then, require the org.apache.onami.lifecycle.core.Stager<PreDestroy> injection to shutdown the application:
import org.apache.onami.lifecycle.core.Stager;
import com.google.inject.TypeLiteral;
...
Runtime.getRuntime().addShutdownHook( new Thread()
{
public void run()
{
injector.getInstance( new TypeLiteral<Stager<PreDestroy>>() {} ).stage();
// or
// preDestroyModuleInstance.getStager().stage();
}
} );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;
import org.apache.onami.lifecycle.core.Stager;
import com.google.inject.TypeLiteral;
public final class ContextListener
implements ServletContextListener
{
private Injector injector;
public void contextDestroyed( ServletContextEvent event )
{
injector.getInstance( new TypeLiteral<Stager<PreDestroy>>() {} ).stage();
}
public void contextInitialized( ServletContextEvent event )
{
...
}
}Users interested on tracking/logging/... objects dispose progresses, can register a org.apache.onami.lifecycle.core.StageHandler, which has the following methods signatures:
public interface StageHandler
{
<I> void onSuccess( I injectee );
<I, E extends Throwable> void onError( I injectee, E error );
}A StageHandler instance can be passed to Stager#stage() method:
injector.getInstance( new TypeLiteral<Stager<PreDestroy>>() {} ).stage( new StageHandler()
{
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 release resources of " + injectee, error );
}
} );