如何打印Guice当前绑定信息及Provider调用的依赖链
1. Printing Guice's In-Progress Bindings
To see bindings as Guice completes them, you have a couple straightforward options:
Enable Development Stage & Debug Logging: When creating your Injector, use
Stage.DEVELOPMENTand configure your logging framework to outputDEBUGlevel logs for thecom.google.injectpackage. Guice will automatically log each binding it sets up, including the type, scope, and provider details. For example:Injector injector = Guice.createInjector(Stage.DEVELOPMENT, new YourModule());Make sure your logger (like SLF4J or java.util.logging) is set to log
com.google.injectat DEBUG—this will dump every binding step as it happens.Manual Binding Debugging: For specific bindings, you can call
debug()directly on the binding statement in your module. This will log detailed info for just that binding:bind(Bar.class).toProvider(BarProvider.class).debug();
2. Tracking Provider Invocation Dependency Chains
Guice doesn’t have a built-in getDependencyChain() method, but you can easily capture and filter the stack trace in your Provider to see exactly where it’s being injected. Here’s how to do it for your BarProvider:
public class BarProvider implements Provider<Bar> { @Override public Bar get() { // Capture the current stack trace StackTraceElement[] stackTrace = new Throwable().getStackTrace(); System.out.println("BarProvider called from:"); // Filter out Guice internal classes to focus on your application code for (StackTraceElement element : stackTrace) { String className = element.getClassName(); // Skip Guice, JDK, and other non-application packages if (!className.startsWith("com.google.inject.") && !className.startsWith("java.") && !className.startsWith("javax.")) { System.out.println(" at " + element); } } // Your existing provider logic here return new Bar(); } }
This will output a clean stack trace showing exactly which classes are injecting Bar (and thus triggering the Provider). For example, if both Foo and Baz inject Bar, you’ll see two distinct stack traces pointing to Foo’s constructor/injection point and Baz’s.
If you want more structured data, you could also use Guice’s TypeListener to track every injection of Bar. Register a listener in your module that logs the injection context whenever Bar is injected:
public class YourModule extends AbstractModule { @Override protected void configure() { bindListener(Matchers.only(Bar.class), new TypeListener() { @Override public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) { encounter.register((MembersInjector<I>) instance -> { System.out.println("Bar injected into: " + instance.getClass().getName()); // Optional: capture stack trace here too }); } }); } }
This will log every time Bar is injected into another object, giving you a clear view of all injection sites.
内容的提问来源于stack exchange,提问作者MageWind

