如何在DropWizard应用中局部使用Guice依赖注入无需全局改造
如何在DropWizard-Guice中无需全局传递Injector就能访问Guice实例
当然可以!你完全可以在不全面改造项目的前提下,逐步用Guice管理的实例替换现有对象。针对你的DropWizard-Guice集成场景,有几种简单的方案来访问Guice Injector或直接获取实例,不用全局传递Injector参数:
方案1:将GuiceBundle作为Application类的成员变量
HubSpot的GuiceBundle本身持有初始化后的Injector实例,你只需要把它从initialize方法里的局部变量改成类的成员变量,就能在run方法或者其他需要的地方直接获取Injector:
public class HelloWorldApplication extends Application<HelloWorldConfiguration> { // 把GuiceBundle改成成员变量 private GuiceBundle<HelloWorldConfiguration> guiceBundle; public static void main(String[] args) throws Exception { new HelloWorldApplication().run(args); } @Override public void initialize(Bootstrap<HelloWorldConfiguration> bootstrap) { guiceBundle = GuiceBundle.<HelloWorldConfiguration>newBuilder() .addModule(new HelloWorldModule()) .enableAutoConfig(getClass().getPackage().getName()) .setConfigClass(HelloWorldConfiguration.class) .build(); bootstrap.addBundle(guiceBundle); } @Override public String getName() { return "hello-world"; } @Override public void run(HelloWorldConfiguration helloWorldConfiguration, Environment environment) throws Exception { // 直接从成员变量获取Injector Injector injector = guiceBundle.getInjector(); // 用Injector获取Guice管理的实例,替换现有代码中的对象 YourExistingService guiceManagedService = injector.getInstance(YourExistingService.class); oldComponent.setService(guiceManagedService); } }
方案2:用静态持有者类在全局范围访问Injector
如果需要在非Application类的其他地方(比如旧的工具类、控制器)获取Guice实例,可以创建一个简单的静态持有者类,在Application初始化完成后注入Injector,之后任何地方都能直接调用:
首先创建持有者类:
public class GuiceInjectorHolder { private static Injector injector; // 仅在Application初始化时调用一次 public static void initialize(Injector injector) { GuiceInjectorHolder.injector = injector; } // 获取Injector public static Injector getInjector() { return injector; } // 封装直接获取实例的方法,简化调用 public static <T> T getInstance(Class<T> clazz) { return injector.getInstance(clazz); } }
然后在Application的run方法里初始化这个持有者:
@Override public void run(HelloWorldConfiguration helloWorldConfiguration, Environment environment) throws Exception { Injector injector = guiceBundle.getInjector(); GuiceInjectorHolder.initialize(injector); // 之后在任意类中都可以这样获取实例 AnotherService service = GuiceInjectorHolder.getInstance(AnotherService.class); legacyServiceWrapper.setDelegate(service); }
注意事项
- 静态持有者是过渡方案,适合你的逐步改造场景。等你把所有旧代码都迁移到Guice注入后,建议移除这个静态类,改用构造注入或字段注入(配合
@Inject),避免静态依赖带来的测试和维护问题。 - 如果你用了
enableAutoConfig,Guice会自动扫描指定包下的类,对带有@Inject构造函数的类进行注入,新增的类可以直接用这种方式,不用手动通过Injector获取。
内容的提问来源于stack exchange,提问作者best wishes
相关产品推荐
相关产品推荐

