Guice TypeListener is not notified about the entered class Type

I have the following Guice module:

class MyModule extends AbstractModule { @Override protected void configure() { bindListener(Matchers.any(), new TypeListener() {...}); } @Provides SomeClass createSomeClass(final Parameter param) { log(param.getValue()); <-- this gets logged ... } } 

What I found strange is that my TypeListener does not receive notification of type Parameter . Even if the provider is called beign and returns SomeClass . I also see the log report so clearly that Parameter was introduced by Guice.

 @Override protected void configure() { bind(Parameter.class); bindListener(Matchers.any(), new TypeListener() {...}); } 

I know Untargetted bindings and statement:

Unbound binding informs the injector about the type, so it can prepare dependencies with impatience.

I would still expect Guice to call TypeListener for any type that is either explicitly bound or injected for the first time.

So what do I need to do unmarketed binding for such classes as a rule?

NOTE. labeling the Parameter constructor with @Inject does not solve the problem.

EDIT:

A complete example (hope I don't leave too much garbage) looks like this:

 public class TestGuice { public static void main(String[] args) { Injector parentInjector = Guice.createInjector(new ParentModule()); Injector childInjector = parentInjector.createChildInjector(new SubModule()); childInjector.getInstance(Runnable.class).run(); } static class ParentModule extends AbstractModule { @Override protected void configure() { } } static class SubModule extends AbstractModule { @Override protected void configure() { bind(SampleInjectedClass.class); // <-- Comment/uncomment here final TypeListener typeListener = new TypeListener() { public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) { System.out.println("Type: " + type.getRawType()); } }; bindListener(Matchers.any(), typeListener); } @Provides Runnable createRunnable(final SampleInjectedClass sampleClass) { return new Runnable() { @Override public void run() { sampleClass.test(); } }; } } static class SampleInjectedClass { public void test() { System.out.println("Test"); } } } 

If a string is present, the output is:

Type: class com.barcap.test.TestGuice $ SampleInjectedClass

Type: class com.google.inject.internal.ProviderMethod

Test

If I delete the line, I get:

Type: class com.google.inject.internal.ProviderMethod

Test

I noticed that if the injector was not created using the createChildInjector code, bind(...) not required.

+7
java guice
source share
2 answers

If possible, exact-time bindings are created for the child injectors, if possible in the ancestor injector . This means that without the string bind(SampleInjectedClass.class); a binding is created in the parent injector for SampleInjectedClass . Since the parent injector does not have your TypeListener , it will not TypeListener .

+3
source share

Can you check your code? In my test on Guice 3, I could not reproduce what you see .

Also, from TypeListener Docs , underscoring my and typo sic:

public abstract void hear (TypeLiteral<I> type, TypeEncounter<I> encounter)

Called when Guice encounters a new type suitable for installing a constructor or members. Called when an injector is created (or an afterword if Guice encounters a type at runtime and creates a JIT binding) .

Although all other dependencies will be called on the TypeListener immediately after creating the injector, there will be no implicit (just-in-time) bindings.

However, based on my example above, it seems that when a parameter is included in the provider method, it registers with the same listener immediately. Can you create a short standalone example that shows the behavior you are asking for?

0
source share

All Articles