结合@Provides 和@Inject
Combining @Provides and @Inject
我最近发现一些代码在同一方法上同时使用了 @Provides
和 @Inject
注释。此方法有两个非原始参数和一个非 void return 类型。
我想知道同时使用这两个是否有意义。据我所知 gather/speculate,似乎 @Inject
用于使用 Guice 构造方法依赖项,而 @Provides
用于绑定 return 类型。任何想法将不胜感激。
不,您绝不会在同一方法上看到 @Provides
and @Inject
。
@Inject
对 构造函数、方法和字段有意义:
- 在构造函数上,标记DI框架应该调用的构造函数。该框架提供所有参数值。这通常称为构造函数注入。
- 在字段上,表示DI框架应该从外部设置字段。框架提供字段值。这通常被称为字段注入。
- 在方法上,表示构建DI框架后,应该exactly调用一次方法。框架提供参数值。 return 值没有意义,通常是
void
。这通常被称为方法注入。
例如:
public class YourInjectableClass {
// Guice will use this constructor...
@Inject public YourInjectableClass(YourDep dep) { /* ... */ }
// ...instead of this one
public YourInjectableClass(YourDep dep, YourOtherDep otherDep) { /* ... */ }
// Guice will populate this field after construction.
@Inject YourField yourField;
@Inject public void register(Registry registry) {
// Guice will create or get a Registry and call this method after
// construction. It sometimes makes sense for this to be protected
// or package-private so this class's consumers aren't tempted
// to call it themselves.
}
}
@Provides
has a much narrower purpose: When used in Guice modules, @Provides
goes on methods and indicates that Guice should call the method whenever it needs an instance of the method's possibly-parameterized type (and inheriting the binding annotations or qualifiers from the method itself). Dagger has a similar @Provides
annotation,因为 @Provides
未在 JSR-330 依赖项注入标准中定义。
对于 Guice 和 Dagger,框架将在调用方法时提供 @Provides
方法的参数,而不使用 @Inject
。 @Inject
的语义无论如何都没有意义,因为即使以与上面的方法注入类似的方式提供参数,框架也可能重复调用 @Provides
方法,但 @Inject
方法只被调用一次。
public class YourModule extends AbstractModule {
@Override public void configure() {) // still needed for AbstractModule
// Guice will call this whenever it needs a
// @SomeBindingAnnotation YourInstance. Because you list a YourDep as a
// parameter, Guice will get and pass in a YourDep.
@Provides @SomeBindingAnnotation YourInstance create(YourDep dep) {
return YourInstanceFactory.create(dep);
}
}
因此,您几乎不应该在同一个文件中看到这些注释,更不用说在同一个方法上了。唯一的例外是,如果您遵循制作本身可注入的模块的可疑做法(可能是从一个注入器获取注入模块以配置不同的注入器),即使这样您也不会在相同的方法上看到它们: @Inject
方法被调用一次以存储依赖项,并且 @Provides
方法应在需要新实例时调用。
我最近发现一些代码在同一方法上同时使用了 @Provides
和 @Inject
注释。此方法有两个非原始参数和一个非 void return 类型。
我想知道同时使用这两个是否有意义。据我所知 gather/speculate,似乎 @Inject
用于使用 Guice 构造方法依赖项,而 @Provides
用于绑定 return 类型。任何想法将不胜感激。
不,您绝不会在同一方法上看到 @Provides
and @Inject
。
@Inject
对 构造函数、方法和字段有意义:
- 在构造函数上,标记DI框架应该调用的构造函数。该框架提供所有参数值。这通常称为构造函数注入。
- 在字段上,表示DI框架应该从外部设置字段。框架提供字段值。这通常被称为字段注入。
- 在方法上,表示构建DI框架后,应该exactly调用一次方法。框架提供参数值。 return 值没有意义,通常是
void
。这通常被称为方法注入。
例如:
public class YourInjectableClass {
// Guice will use this constructor...
@Inject public YourInjectableClass(YourDep dep) { /* ... */ }
// ...instead of this one
public YourInjectableClass(YourDep dep, YourOtherDep otherDep) { /* ... */ }
// Guice will populate this field after construction.
@Inject YourField yourField;
@Inject public void register(Registry registry) {
// Guice will create or get a Registry and call this method after
// construction. It sometimes makes sense for this to be protected
// or package-private so this class's consumers aren't tempted
// to call it themselves.
}
}
@Provides
has a much narrower purpose: When used in Guice modules, @Provides
goes on methods and indicates that Guice should call the method whenever it needs an instance of the method's possibly-parameterized type (and inheriting the binding annotations or qualifiers from the method itself). Dagger has a similar @Provides
annotation,因为 @Provides
未在 JSR-330 依赖项注入标准中定义。
对于 Guice 和 Dagger,框架将在调用方法时提供 @Provides
方法的参数,而不使用 @Inject
。 @Inject
的语义无论如何都没有意义,因为即使以与上面的方法注入类似的方式提供参数,框架也可能重复调用 @Provides
方法,但 @Inject
方法只被调用一次。
public class YourModule extends AbstractModule {
@Override public void configure() {) // still needed for AbstractModule
// Guice will call this whenever it needs a
// @SomeBindingAnnotation YourInstance. Because you list a YourDep as a
// parameter, Guice will get and pass in a YourDep.
@Provides @SomeBindingAnnotation YourInstance create(YourDep dep) {
return YourInstanceFactory.create(dep);
}
}
因此,您几乎不应该在同一个文件中看到这些注释,更不用说在同一个方法上了。唯一的例外是,如果您遵循制作本身可注入的模块的可疑做法(可能是从一个注入器获取注入模块以配置不同的注入器),即使这样您也不会在相同的方法上看到它们: @Inject
方法被调用一次以存储依赖项,并且 @Provides
方法应在需要新实例时调用。