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 ); } } );