[ https://issues.apache.org/jira/browse/ONAMI-102?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14042279#comment-14042279 ]
Mikhail Mazursky commented on ONAMI-102: ---------------------------------------- [~simone.tripodi], here are some examples and more details (I cannot implement them as tests because I haven't committed any code yet): # I have defined an additional interface (with obvious implementation that I omit here) to help with ExecutorServices and AutoCloseables. We can use just Closeable to be compatible with Java < 1.7 {code:java} public interface AdvancedStager<A extends Annotation> extends Stager<A> { <T extends ExecutorService> T register(T executor); <T extends AutoCloseable> T register(T closeable); } {code} # I'm only interested in PreDestroy annotation handling so I defined a module that handles it: {code:java} public class Jsr250Module extends LifeCycleStageModule { private final AdvancedStager<PreDestroy> advStager = new DefaultAdvancedStager<>( PreDestroy.class, DefaultStager.Order.FIRST_IN_LAST_OUT); @Override protected void configureBindings() { bind(new TypeLiteral<AdvancedStager<PreDestroy>>() {}).toInstance(advStager); bindStager(advStager).matching(new AbstractMatcher<TypeLiteral<?>>() { @Override public boolean matches(TypeLiteral<?> typeLiteral) { Package pkg = typeLiteral.getRawType().getPackage(); return pkg != null && pkg.getName().startsWith("com.my.project."); } }); } public AdvancedStager<PreDestroy> getStager() { return advStager; } } {code} This module can easily be extended to support PostConstruct (and anything else) using two stagers, etc. It is possible to use several lifecycle modules for different annotations. # Usage in a module is trivial {code:java} @Provides @Singleton public ExecutorService provideExecutor(AdvancedStager<PreDestroy> stager) { return stager.register(Executors.newCachedThreadPool()); } {code} # Usage to execute stage (i.e. close objects in our case) is simple too. Here is a pattern for unit tests. If injector creation fails we still shutdown those executors and other stuff Guice managed to instantiate before it failed {code:java} public class SomeUnitTest { private Injector injector; private Stager<PreDestroy> stager; @BeforeClass public void beforeClass() { Jsr250Module jsr250Module = new Jsr250Module(); stager = jsr250Module.getStager(); try { injector = Guice.createInjector(jsr250Module /* and other modules */); injector.injectMembers(this); // init other stuff that can throw exceptions } catch (Throwable e) { stager.stage(); throw e; } } @AfterClass public void afterClass() { stager.stage(); } } {code} WDYT? > Redesign the Modules structure in order to simply APIs usage > ------------------------------------------------------------ > > Key: ONAMI-102 > URL: https://issues.apache.org/jira/browse/ONAMI-102 > Project: Apache Onami > Issue Type: Improvement > Components: lifecycle > Affects Versions: lifecycle-0.2.0 > Reporter: Simone Tripodi > Assignee: Mikhail Mazursky > Fix For: lifecycle-0.2.0 > > Attachments: LifeCycleModule.java, LifeCycleStageModule.java > > > We already started discussing about it in the ML, but let's track progresses > on JIRA. > I detected few areas of approaching the lifecycle design: > * IIUC, we want to manage a series of annotations which identify the > sequence of staging steps in the lifecycle, so IMHO the > AbstractLifeCycleModule constructor with just one annotation has to > disappear; it would be nice to have a varargs array, which would simplify the > signature - and the usage from our users - but it would generate an annoying > warning to our users; IMHO it is still acceptable, but in case we don't find > an agreement here, Iterable should be the best way to pass the annotations > sequence to the module. > * ListBuilder: as already discussed, this sound too generic: I'd propose > something like AnnotationsLifecycleSequenceBuilder (maybe it is too verbose > :P) but I'd opt for something that gives a precise idea, not a generic one; > * Again on the list builder, as we discussed, IMHO the wrapped data > structure should be a LinkedHashSet: it preserves the sequence and makes > efficient the check for duplicates - if the list has a duplicate, I bet the > lifecycle event would be handled twice; > * Builder pattern: the way to get the builder is IMHO a little too verbose: > Builder.newBuilder() is not a pattern that makes me particularly happy, I'd > rather opt for inner class builder such as {{new ConcreteClass.Builder()}} > which is used in the AsyncHttpClient - WDYT? > I can even make a proposal, in order to show you better my ideas, and attach > a patch to discuss together -- This message was sent by Atlassian JIRA (v6.2#6252)