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
-~----------~----~----~----~------~----~------~--~---

Reply via email to