Следующее делает именно то, что я просил.Хотя он не синтезирует реализацию фабрики, он достаточно хорош, поскольку фабрика имеет доступ к контексту инъекции , чтобы можно было использовать другие bean (инъецируемые артефакты) во время построения.Он использует @Configuration
на основе Java вместо XML, но он также будет работать с XML.
Заводской интерфейс:
public interface Robot {
}
// Implementation of this is to be injected by the IoC in the Robot instances
public interface Brain {
String think();
}
public class RobotImpl implements Robot {
private final String name_;
private final Brain brain_;
@Inject
public RobotImpl(String name, Brain brain) {
name_ = name;
brain_ = brain;
}
public String toString() {
return "RobotImpl [name_=" + name_ + "] thinks about " + brain_.think();
}
}
public class RobotBrain implements Brain {
public String think() {
return "an idea";
}
}
// The assisted factory type
public interface RobotFactory {
Robot newRobot(String name);
}
// это конфигурация Spring, показывающая, как сделать вспомогательную инъекцию
@Configuration
class RobotConfig {
@Bean @Scope(SCOPE_PROTOTYPE)
public RobotFactory robotFactory() {
return new RobotFactory() {
@Override
public Robot newRobot(String name) {
return new RobotImpl(name, r2dxBrain());
}
};
}
@Bean @Scope(SCOPE_PROTOTYPE)
public Brain r2dxBrain() {
return new RobotBrain();
}
}
Тестовый код:
public class RobotTest {
@Test
public void t1() throws Exception {
ApplicationContext ctx = new
AnnotationConfigApplicationContext(RobotConfig.class);
RobotFactory rf = ctx.getBean(RobotFactory.class);
assertThat(rf.newRobot("R2D2").toString(),
equalTo("RobotImpl [name_=R2D2] thins about an idea"));
}
}
Это достигается именно таким, как Guiceделает.Сложная разница - Scope
.По умолчанию Spring имеет значение Singleton
, а Guice - нет (это прототип).