Guice辅助注射,绑定订单
Guice assisted inject, binding order
我运行在实施辅助注射时出错。
辅助注射一直有效,直到我引入了另一个名为 Manager 的 class,它依赖于辅助 Person
class。经理想使用 Person (@Assited Address)
。代码在构造注入器图时中断。它不会更进一步。
Injector injector = Guice.createInjector(myModule);
直觉上,我理解当对象 A 被辅助时,B(依赖于 A)实际上也通过 A 隐式地被辅助。
请注意,我检查过。我想 ColinD 这样的人肯定知道答案
How to use Guice's AssistedInject?
How to bind Assisted Injected class to interface?
出于好奇,是否有很好的 techniques/tools 来发现 Guice 错误配置和缓解学习曲线?我打开了 ProvisionListener 并使用了图形库。这有点帮助。
public class Person implements PersonInterface {
private String name;
private Address address;
@Inject
public Person(String name, @Assisted Address address) {
this.name = name;
this.address = address;
}
}
public interface PersonInterface {
public String getName();
public Address getAddress();
}
public interface PersonFactory {
public PersonInterface create(Address address);
}
public class Address {
private final String address;
public Address(String address) {
super();
this.address = address;
}
}
public class Manager implements IManager {
private final Person person;
@Inject
public Manager(Person person) {
this.person=person;
}
...
}
configure() {
install(new FactoryModuleBuilder()
.implement(PersonInterface.class, Person.class)
.build(PersonFactory.class));
//
bind(IManager.class).to(Manager.class);
}
实际错误是
com.google.inject.CreationException: Unable to create injector, see the following errors:
1) No implementation for ...assisted_inject.Address annotated with @com.google.inject.assistedinject.Assisted(value=) was bound.
while locating ....assisted_inject.Address annotated with @com.google.inject.assistedinject.Assisted(value=)
for parameter 2 at ....assisted_inject.Person.<init>(Person.java:13)
当您将此绑定放入您的模块时:
bind(IManager.class).to(Manager.class);
Guice 将尝试创建 Manager
class 的新实例。它寻找一个(但只有一个)用 @Inject
注释的构造函数或作为非私有的回退零参数构造函数。这是 Guice 将使用的构造函数:
@Inject
public Manager(Person person) {
this.person=person;
}
现在遵循相同的规则,Guice 将尝试使用适当的构造函数实例化一个 Person
,它会卡在这里:
@Inject
public Person(String name, @Assisted Address address) {
this.name = name;
this.address = address;
}
由于@Assisted
注解,尝试实例化地址时会放弃。这个注解是一个 BindingAnnotation 并且 Guice 会特别对待它们 - 它会尝试为它们找到显式绑定并且有 none。阅读有关绑定注释的内容,您就会明白为什么。
由于您的经理是有状态的并且显然管理一个人,您可能希望为这些经理创建一个工厂,例如:
public interface IManagerFactory {
public IManager getIManager(PersonInterface p);
}
那么你会得到一个IManager
,例如:
public interface IManager {
public String getPersonName();
}
以及使用辅助注入的实现:
public class Manager implements IManager {
private final PersonInterface person;
@Inject
public Manager(@Assisted PersonInterface person) {
this.person = person;
}
@Override
public String getPersonName() {
return person.getName();
}
}
您可以在您的模块中绑定这些:
class MyModule extends AbstractModule {
protected void configure() {
install(new FactoryModuleBuilder()
.implement(PersonInterface.class, Person.class)
.build(PersonFactory.class));
install(new FactoryModuleBuilder()
.implement(IManager.class, Manager.class)
.build(IManagerFactory.class));
}
}
注入工厂:
@Inject
PersonFactory pf;
@Inject
IManagerFactory manF;
并相应地使用它们,例如:
public void testGuice() {
PersonInterface pi = pf.create(new Address("boh"));
IManager im = manF.getIManager(pi);
System.out.println(im.getPersonName());
}
我运行在实施辅助注射时出错。
辅助注射一直有效,直到我引入了另一个名为 Manager 的 class,它依赖于辅助 Person
class。经理想使用 Person (@Assited Address)
。代码在构造注入器图时中断。它不会更进一步。
Injector injector = Guice.createInjector(myModule);
直觉上,我理解当对象 A 被辅助时,B(依赖于 A)实际上也通过 A 隐式地被辅助。
请注意,我检查过。我想 ColinD 这样的人肯定知道答案 How to use Guice's AssistedInject? How to bind Assisted Injected class to interface?
出于好奇,是否有很好的 techniques/tools 来发现 Guice 错误配置和缓解学习曲线?我打开了 ProvisionListener 并使用了图形库。这有点帮助。
public class Person implements PersonInterface {
private String name;
private Address address;
@Inject
public Person(String name, @Assisted Address address) {
this.name = name;
this.address = address;
}
}
public interface PersonInterface {
public String getName();
public Address getAddress();
}
public interface PersonFactory {
public PersonInterface create(Address address);
}
public class Address {
private final String address;
public Address(String address) {
super();
this.address = address;
}
}
public class Manager implements IManager {
private final Person person;
@Inject
public Manager(Person person) {
this.person=person;
}
...
}
configure() {
install(new FactoryModuleBuilder()
.implement(PersonInterface.class, Person.class)
.build(PersonFactory.class));
//
bind(IManager.class).to(Manager.class);
}
实际错误是
com.google.inject.CreationException: Unable to create injector, see the following errors:
1) No implementation for ...assisted_inject.Address annotated with @com.google.inject.assistedinject.Assisted(value=) was bound.
while locating ....assisted_inject.Address annotated with @com.google.inject.assistedinject.Assisted(value=)
for parameter 2 at ....assisted_inject.Person.<init>(Person.java:13)
当您将此绑定放入您的模块时:
bind(IManager.class).to(Manager.class);
Guice 将尝试创建 Manager
class 的新实例。它寻找一个(但只有一个)用 @Inject
注释的构造函数或作为非私有的回退零参数构造函数。这是 Guice 将使用的构造函数:
@Inject
public Manager(Person person) {
this.person=person;
}
现在遵循相同的规则,Guice 将尝试使用适当的构造函数实例化一个 Person
,它会卡在这里:
@Inject
public Person(String name, @Assisted Address address) {
this.name = name;
this.address = address;
}
由于@Assisted
注解,尝试实例化地址时会放弃。这个注解是一个 BindingAnnotation 并且 Guice 会特别对待它们 - 它会尝试为它们找到显式绑定并且有 none。阅读有关绑定注释的内容,您就会明白为什么。
由于您的经理是有状态的并且显然管理一个人,您可能希望为这些经理创建一个工厂,例如:
public interface IManagerFactory {
public IManager getIManager(PersonInterface p);
}
那么你会得到一个IManager
,例如:
public interface IManager {
public String getPersonName();
}
以及使用辅助注入的实现:
public class Manager implements IManager {
private final PersonInterface person;
@Inject
public Manager(@Assisted PersonInterface person) {
this.person = person;
}
@Override
public String getPersonName() {
return person.getName();
}
}
您可以在您的模块中绑定这些:
class MyModule extends AbstractModule {
protected void configure() {
install(new FactoryModuleBuilder()
.implement(PersonInterface.class, Person.class)
.build(PersonFactory.class));
install(new FactoryModuleBuilder()
.implement(IManager.class, Manager.class)
.build(IManagerFactory.class));
}
}
注入工厂:
@Inject
PersonFactory pf;
@Inject
IManagerFactory manF;
并相应地使用它们,例如:
public void testGuice() {
PersonInterface pi = pf.create(new Address("boh"));
IManager im = manF.getIManager(pi);
System.out.println(im.getPersonName());
}