gpt4 book ai didi

java - 不带 OUT 注解的 Guice 构造函数注入(inject)?

转载 作者:行者123 更新时间:2023-11-29 04:18:23 29 4
gpt4 key购买 nike

有人可以帮助实现不带 OUT 注释的 Guice 吗?

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.xml

    <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“指向”正确的构造函数......而不是使用注释。

如您所见,使用默认/空构造函数不是一个好的选择,因为这个示例很简单,但我想坚持使用基于构造函数的注入(inject)。

追加:

根据我在评论中从 Hemant Singh 那里得到的“提示”,我想我更接近了。

我创建了一个 ProductionInjectModule,它使用

bind(MyInterface.class).toConstructor(MyConcrete.class.getConstructor(org.apache.commons.logging.Log.class));

但即使我通过指向特定的构造函数(使用“toConstructor”)来“强制”解决这个问题......我仍然得到:

Classes must have either one (and only one) constructor annotated with @Inject or a zero-argument constructor that is not private.

啊啊啊啊啊啊啊啊啊!

下面是完整的“模块”代码:

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

You can also inject a dependency that doesn’t have a default no-arg constructor using constructor binding:

>     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

constructor that takes a boolean argument. We supply the true argument to the constructor by defining an untargeted binding of the Boolean class.

This untargeted binding will be eagerly supplied to any constructor in the binding that accepts a boolean parameter. With this approach, all dependencies of Communication are injected.

Another approach to constructor-specific binding is the instance binding, where we provide an instance directly in the binding:

>     public class BasicModule extends AbstractModule {
>
> @Override
> protected void configure() {
> bind(Communication.class)
> .toInstance(new Communication(true));
> } }

2019 年夏季附录:

使用“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

Embedded components such as libraries or frameworks should not declare a dependency on any SLF4J binding but only depend on slf4j-api. When a library declares a compile-time dependency on a SLF4J binding, it imposes that binding on the end-user, thus negating SLF4J's purpose. When you come across an embedded component declaring a compile-time dependency on any SLF4J binding, please take the time to contact the authors of said component/library and kindly ask them to mend their ways.

最佳答案

我明白了!我在原始问题中的“附加:”区域很接近!但现在我看到了我的小错误。

我上面的 ProductionInjectModule 是正确的。

我的“要求解决”是错误的。

请注意,在我的 getInstance 中,我还有具体内容。

我需要这个:(强调 getInstance 的参数)

IVehicle veh = injector.getInstance(IVehicle.class);
int wc = veh.getWheelCount();

IAnimal amh = injector.getInstance(IAnimal.class);
amh.makeNoise();

完整的工作代码:(带有上面的接口(interface)和具体内容)

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 年夏季附录:

使用“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

Embedded components such as libraries or frameworks should not declare a dependency on any SLF4J binding but only depend on slf4j-api. When a library declares a compile-time dependency on a SLF4J binding, it imposes that binding on the end-user, thus negating SLF4J's purpose. When you come across an embedded component declaring a compile-time dependency on any SLF4J binding, please take the time to contact the authors of said component/library and kindly ask them to mend their ways.

关于java - 不带 OUT 注解的 Guice 构造函数注入(inject)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50846677/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com