有人可以帮助实现Guice withOUT注释吗?
public interface IAnimal {
void makeNoise();
}
public interface IVehicle {
int getWheelCount();
}
import org.apache.commons.logging.Log;
public class Car implements IVehicle {
private Log Logger;
public Car(Log lgr) {
this.Logger = lgr;
}
public final int getWheelCount() {
this.Logger.info("getWheelCount is returning 4");
return 4;
}
}
import org.apache.commons.logging.Log;
public class Dog implements IAnimal {
private Log Logger;
public Dog(Log lgr) {
this.Logger = lgr;
}
public final void makeNoise() {
this.Logger.info("Bark Bark Bark");
}
}
pom.hml
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>4.2.0</version>
</dependency>
我尝试过的:
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.google.inject.*;
public class App {
public static void main(String[] args) {
Log localLogger =
LogFactory.getLog(App.class);
Injector injector = Guice.createInjector();
IVehicle veh = injector.getInstance(Car.class);
int wc = veh.getWheelCount();
IAnimal amh = injector.getInstance(Dog.class);
amh.makeNoise();
}
}
我得到的错误是:
Classes must have either one (and only one) constructor annotated with @Inject or a zero-argument constructor that is not private.
我理解错误。
但是我希望我可以将Guice“指向”正确的构造函数......而不是使用注释。
正如您所看到的,使用默认/空构造函数不是一个好选择,因为这个示例很简单,但我想坚持使用基于构造函数的注入。
附加:
基于我在评论中从Hemant Singh那里得到的“暗示”,我想我离得更近了。
我创建了一个使用的ProductionInjectModule
bind(MyInterface.class).toConstructor(MyConcrete.class.getConstructor(org.apache.commons.logging.Log.class));
但即使我通过指向特定的构造函数(使用“toConstructor”)来“强迫”该问题.......我仍然得到:
类必须有一个(也是唯一一个)使用@Inject注释的构造函数或一个非私有的零参数构造函数。
Gaaaaaaaaaaaaaaaaaaaaa!
完整的“模块”代码如下:
public class App {
public static void main(String[] args) {
runGuice();
}
private static void runGuice() {
Log localLogger = LogFactory.getLog(App.class);
ProductionInjectModule pm = new ProductionInjectModule(localLogger);
Injector injector = Guice.createInjector(pm);
////Injector injector = Guice.createInjector();
//// injector.injectMembers(localLogger);
IVehicle veh = injector.getInstance(Car.class);
int wc = veh.getWheelCount();
IAnimal amh = injector.getInstance(Dog.class);
amh.makeNoise();
}
}
import com.google.inject.AbstractModule;
import com.google.inject.Module;
public class ProductionInjectModule extends AbstractModule implements Module {
// public void configure(Binder binder) {
// binder.bind(IVehicle.class).to(Car.class);
//// binder.bind(InterfaceB.class).to(ConcreteB.class);
//// binder.bind(InterfaceC.class).to(ConcreteC.class);
// }
private final org.apache.commons.logging.Log Logger;
public ProductionInjectModule(org.apache.commons.logging.Log concreteLogger) {
this.Logger = concreteLogger;
}
@Override
protected void configure() {
try {
bind(org.apache.commons.logging.Log.class).toInstance(this.Logger);
bind(IVehicle.class).toConstructor(Car.class.getConstructor(org.apache.commons.logging.Log.class));
bind(IAnimal.class).toConstructor(Dog.class.getConstructor(org.apache.commons.logging.Log.class));
} catch (NoSuchMethodException e) {
addError(e);
}
}
}
并按照相同的提示,我找到了一些支持的文档:
来自:http://www.baeldung.com/guice
您还可以使用构造函数绑定注入没有默认no-arg构造函数的依赖项:
> public class BasicModule extends AbstractModule {
>
> @Override
> protected void configure() {
> bind(Boolean.class).toInstance(true);
> bind(Communication.class).toConstructor(
> Communication.class.getConstructor(Boolean.TYPE)); }
The snippet above will inject an instance of Communication using the
采用布尔参数的构造函数。我们通过定义Boolean类的无对齐绑定为构造函数提供了真正的参数。
这个非目标绑定将热切地提供给接受布尔参数的绑定中的任何构造函数。通过这种方法,可以注入通信的所有依赖关系。
构造函数特定绑定的另一种方法是实例绑定,我们在绑定中直接提供实例:
> public class BasicModule extends AbstractModule {
>
> @Override
> protected void configure() {
> bind(Communication.class)
> .toInstance(new Communication(true));
> } }
2019年夏季APPEND:
使用“slf4j”而不是“org.apache.commons”会更明智一些
org.slf4j.Logger
and
org.slf4j.LoggerFactory.getLogger(MyClass.class);
和
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
为什么?
https://www.slf4j.org/codes.html#multiple_bindings
嵌入式组件(如库或框架)不应声明对任何SLF4J绑定的依赖性,而仅依赖于slf4j-api。当库声明对SLF4J绑定的编译时依赖性时,它会对最终用户强制绑定,从而否定SLF4J的用途。当您遇到一个嵌入式组件声明对任何SLF4J绑定的编译时依赖性时,请花时间联系所述组件/库的作者,并请他们修改他们的方法。
我知道了!我原来问题中的“APPEND:”区域很接近!但现在我看到了我的小错误。
我上面的ProductionInjectModule是正确的。
我的“要求解决”是错误的。
请注意,在我的getInstance中,我仍然具体。
我需要这样:(强调getInstance的参数)
IVehicle veh = injector.getInstance(IVehicle.class);
int wc = veh.getWheelCount();
IAnimal amh = injector.getInstance(IAnimal.class);
amh.makeNoise();
完整的工作代码:(具有上面的接口和混凝土)
public class App {
public static void main(String[] args) {
runGuice();
}
private static void runGuice() {
Log localLogger = LogFactory.getLog(App.class);
ProductionInjectModule pm = new ProductionInjectModule(localLogger);
Injector injector = Guice.createInjector(pm);
IVehicle veh = injector.getInstance(IVehicle.class);
int wc = veh.getWheelCount();
IAnimal amh = injector.getInstance(IAnimal.class);
amh.makeNoise();
}
}
import com.google.inject.AbstractModule;
import com.google.inject.Module;
public class ProductionInjectModule extends AbstractModule implements Module {
private final org.apache.commons.logging.Log Logger;
public ProductionInjectModule(org.apache.commons.logging.Log concreteLogger) {
this.Logger = concreteLogger;
}
@Override
protected void configure() {
try {
bind(org.apache.commons.logging.Log.class).toInstance(this.Logger);
bind(IVehicle.class).toConstructor(Car.class.getConstructor(org.apache.commons.logging.Log.class));
bind(IAnimal.class).toConstructor(Dog.class.getConstructor(org.apache.commons.logging.Log.class));
} catch (NoSuchMethodException e) {
addError(e);
}
}
}
2019年夏季APPEND:
使用“slf4j”而不是“org.apache.commons”会更明智一些
org.slf4j.Logger
and
org.slf4j.LoggerFactory.getLogger(MyClass.class);
和
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
当然,检查更新的更新:
https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.slf4j%22%20AND%20a%3A%22slf4j-api%22
为什么?
https://www.slf4j.org/codes.html#multiple_bindings
嵌入式组件(如库或框架)不应声明对任何SLF4J绑定的依赖性,而仅依赖于slf4j-api。当库声明对SLF4J绑定的编译时依赖性时,它会对最终用户强制绑定,从而否定SLF4J的用途。当您遇到一个嵌入式组件声明对任何SLF4J绑定的编译时依赖性时,请花时间联系所述组件/库的作者,并请他们修改他们的方法。