For posterity I thought I would record this here.
I am futzing around with an extension that programmatically turns JSR-330 Providers into producer methods. I am not entirely sure where I'm going with this yet—just kind of exploring, and it's feeling like a dead end—but it has been a great way to get into the nitty gritty details of the CDI SPI.
Anyway, so I wrote an observer method that does this:
public <T extends Provider<?>> void replaceGuiceProviderWithProducerMethod(@Observes final ProcessAnnotatedType<T> event) {
if (event != null) {
final Stream<AnnotatedMethodConfigurator<? super T>> methodStream = event.configureAnnotatedType().filterMethods(m -> {
return m.getJavaMember().getName().equals("get");
});
System.out.println("*** get() method count: " + methodStream.count()); // prints 2!
methodStream.forEach(m -> {
m.add(PRODUCES_LITERAL); // an annotation literal implementing the Produces annotation; this fires twice
});
}
}
One of the more interesting things I found was that if you have a Provider implementation (public class Foo implements Provider<Bar>), that has exactly one declared method in it (public Bar get() { return bar; }), its declared method count is…two. Whaaa…?
If you examine the methods in the stream, you'll see that one is declared, effectively:
public Object get();
…and the other is declared, effectively:
public Bar get();
This was surprising to me. Then I read more deeply about bridge methods and it made sense.
My question, I guess, is: as you can see above, I'm adding @Produces onto the get() method (in the abstract). But do I add it onto both of these AnnotatedMethods, or just the one that returns Bar? I don't want there to be a producer method that manufactures java.lang.Object!