制作自定义@Inject注释

Mic*_*uff 8 guice lombok

我在我的项目中使用了lombok,有很多课程@RequiredArgsConstructors.我希望这些构造函数能够自动用于guice.

一个可行的选择是使用,@RequiredArgsConstructors(onConstructor=@__(@Inject))但这既丑陋又实验性(读:未来可能会从lombok中消失).

我正在考虑做的是制作一个自定义注入注释,比如说@InjectOnlyConstructor我的类定义并使用guice的SPI来绑定这些类型.但我无法弄清楚如何在SPI中发现这些类型.

我怎样才能查看guice的元素并绑定到这些构造函数,而guice会默认拒绝?

我希望类看起来像的示例:

@Singleton
@InjectOnlyConstructor
@RequiredArgsConstructor
public class CatPictureService {
    private final WebServiceClient client;

    // Cool stuff that would make facebook cry
}
Run Code Online (Sandbox Code Playgroud)

作为备份计划,我可以使用一个模块来扫描项目的包并自动绑定这些类型.

Mic*_*uff 2

我开始认为不可能连接到 Guice 来解析未绑定的类型。

\n\n

所以我想出了四种不同的解决方案。第一个是我最喜欢的,它包含官方 Guice 扩展使用的看似明确的接线模式。您可以按如下方式使用它:

\n\n
public class Bar {\n    private Bar(XYZ xyz) { ... }\n}\n\nInjector inject = Guice.createInjector(new AbstractModule() {\n    protected void configure() {\n        install(new OnlyConstructorBuilder(Bar.class));\n    }\n});\n
Run Code Online (Sandbox Code Playgroud)\n\n

OnlyConstructorBuilder定义如下:

\n\n
@RequiredArgsConstructor\nprivate static class OnlyConstructorBuilder extends AbstractModule {\n    private final Class<?> type;\n\n    @Override\n    protected void configure() {\n        bindToOnlyConstructor(type);\n    }\n\n    @SuppressWarnings("unchecked")\n    private <T> void bindToOnlyConstructor(Class<T> type) {\n        Constructor<T>[] ctors = (Constructor<T>[])type.getDeclaredConstructors();\n\n        if (ctors.length > 1) {\n            addError("%s has too many constructors %s", type.getName(), Arrays.toString(ctors));\n            return;\n        } else if (ctors.length < 1) {\n            addError("%s needs at least one constructor", type.getName());\n            return;\n        } else {\n            bind(type).toConstructor(ctors[0]);\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

第二种方法是扫描类路径\xe2\x80\x94 或其部分\xe2\x80\x94 查找特定注释。这是我最初的想法,如果您使用 Guava 的反射助手,这并不太难。我以前也做过类似的事情,但人们觉得它太神奇了。绑定部分与上面类似。

\n\n

第三种方法是bind(Bar.class)在模块中使用 Elements SPI 来查找UntargetedBinding带有特定注释的 s。但由于我已经绑定了该类,因此我也可以绑定到唯一的构造函数。

\n\n

第四种方法是最糟糕的。它使用 Elements API 并确定每个绑定的依赖关系;搜索具有特定注释的未绑定依赖项。这是一条我不想走的路。

\n