Spring Java Config:如何创建一个带有运行时参数的原型范围@Bean?
使用Spring的Java配置,我需要获取/实例化一个原型范围的bean,其构造函数参数只能在运行时获得。请考虑以下代码示例(为简洁起见,进行了简化):
@Autowired
private ApplicationContext appCtx;
public void onRequest(Request request) {
//request is already validated
String name = request.getParameter("name");
Thing thing = appCtx.getBean(Thing.class, name);
//System.out.println(thing.getName()); //prints name
}
其中 Thing 类定义如下:
public class Thing {
private final String name;
@Autowired
private SomeComponent someComponent;
@Autowired
private AnotherComponent anotherComponent;
public Thing(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}
注意是:它只能通过构造函数提供,并保证不可变性。其他依赖项是类的特定于实现的依赖项,不应为请求处理程序实现所知(紧密耦合)。name
final
Thing
此代码与Spring XML配置配合得很好,例如:
<bean id="thing", class="com.whatever.Thing" scope="prototype">
<!-- other post-instantiation properties omitted -->
</bean>
我如何用Java配置实现同样的事情?以下操作在使用 Spring 3.x 时不起作用:
@Bean
@Scope("prototype")
public Thing thing(String name) {
return new Thing(name);
}
现在,我可以创建一个工厂,例如:
public interface ThingFactory {
public Thing createThing(String name);
}
但这违背了使用Spring取代ServiceLocator和Factory设计模式的全部意义,而这种模式非常适合这个用例。
如果Spring Java Config可以做到这一点,我将能够避免:
- 定义工厂接口
- 定义工厂实现
- 为工厂实现编写测试
对于Spring已经通过XML配置支持的东西来说,这是一项艰巨的工作(相对而言)。