Jeremy Chone wrote:
> Hi,
>
> I would like intercept all object created by Guice to check if they
> have init()/shutdown() methods. What is the best way to do that. I am
> getting a little confused with InjectionListener, TypeListener, ...
Hi Jeremy,
you have to write a TypeListener/InjectionListener combination and bind
them in one Module, with a Matcher implementation that retains only
classes that have init/shutdown methods:
public class LifecycleTypeListener implements TypeListener
{
public LifecycleTypeListener(InjectionListener<Object>
injectionListener)
{
_injectionListener = injectionListener;
}
public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter)
{
encounter.register(_injectionListener);
}
final private InjectionListener<Object> _injectionListener;
}
public class LifecycleInjectionListener implements InjectionListener<Object>
{
public void afterInjection(Object injectee)
{
// injectee has init / shutdown methods, you can call them by
reflection
// put your processing here
}
}
public final class Matchers
{
static final public Matcher<TypeLiteral<?>> classSupportsLifecycle()
{
return new AbstractMatcher<TypeLiteral<?>>()
{
public boolean matches(TypeLiteral<?> type)
{
boolean hasInit = false;
boolean hasShutdown = false;
for (Method m: type.getRawType().getMethods())
{
if ("init".equals(m.getName()))
{
hasInit = true;
}
else if ("shutdown".equals(m.getName()))
{
hasShutdown = true;
}
}
return hasInit && hasShutdown;
}
};
}
}
final public class LifecycleModule extends AbstractModule
{
@Override protected void configure()
{
LifecycleInjectionListener injectionListener = new
LifecycleInjectionListener();
requestInjection(injectionListener);
LifecycleTypeListener typeListener = new
LifecycleTypeListener(injectionListener);
bindListener(Matchers.classSupportsLifecycle(), typeListener);
}
}
That's mainly it for your case.
In the example above I took it for granted that you required classes to
have both init AND shutdown methods.
If you want to process a class if it has EITHER of this method, you
would create two different Matchers, 2 different TypeListeners and 2
different InjectionListener, and you would bind both TypeListeners.
Note that the Matcher I put in the example is not very safe in that it
doesn't check whether init/shutdown methods take the right arguments,
this should be further adapted to make sure that only the correct
init()/shutdown() methods are retained.
Note that the situation would be easier if you defined interfaces for
init/shutdown methods and check only for classes that implement these
interfaces, in this case you could improve the InjectionListener as follows:
public class LifecycleInjectionListener implements InjectionListener<?
extends Lifecycle>
{
public void afterInjection(Lifecycle injectee)
{
}
}
And of course, the Matcher would be simpler as well.
Hope this helps
Jean-Francois
> Jeremy,
> --
> Jeremy Chone
> +1 415 699 9912
> www.jeremychone.com <http://www.jeremychone.com>
>
> >
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"google-guice" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/google-guice?hl=en
-~----------~----~----~----~------~----~------~--~---