辅助注射在春天有可能吗?
在Guice 2或3中,此处存在所谓的辅助/部分注入。这个,Guice综合了我的对象的工厂实现(实现我的界面),一些构造函数是Guice注入的,有些是从上下文中提供的。
In Guice 2 or 3, exists so called Assisted/Partial Inject described here. With this, Guice synthesizes factory implementation (implementing my interface) for my object and some of the constructor arguments are injected by Guice, and some are provided from the context.
有可能和Spring如何做同样的事情?
Is it possible and how to do the same thing with Spring?
以下是我所要求的。虽然它不合成工厂的实现,但是由于工厂可以访问注入上下文,因此可以在其中使用其他 bean (可注入工件)施工。它使用基于java的 @Configuration
而不是XML,但它也可以与XML一起工作。
The following does exactly what i asked for. Though, it does not synthesize the implementation of the factory, it is good enough as the factory has access to the injection context so that can use other beans (injectable artifacts) during construction. It uses java based @Configuration
instead of XML, but it will work with XML too.
出厂界面:
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配置,显示如何进行辅助注射
// this is the Spring configuration showing how to do the assisted injection
@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不是(它是原型)。
This achieves exactly what Guice does. The tricky difference is the Scope
. Spring's default scope is Singleton
and Guice's is not (it is prototype).