1

我有一个关于创建新 bean 的小问题。基本上根据请求,我得到一些参数,这些参数需要传递给 bean。下面我为每个请求实例化 ControllerService。相反,我希望它是一个具有 scope=protype 的 bean。这样我就可以为每个请求获得一个新对象。但是,我如何设置通过 bean 中的构造函数发送的 2 个属性(kpiName、kpiInput)?

@Autowired
@Qualifier("serviceManager")
Cleanser serviceManager;  

@RequestMapping(method = RequestMethod.POST)
public @ResponseBody
String getKPIResult(@RequestParam("kpiName") String kpiName,
            @RequestParam("kpiInput") String kpiInput) {    

    return serviceManager.checkAndExecute(new ControllerService(kpiName, kpiInput));
}
4

2 回答 2

1

不。Spring MVC 中的 Controller 主要源自旧的 Java servlet,按照规范,它应该是无状态的。

事实上,控制器对象被硬缓存在处理程序映射框架内,而不是从每个请求的 bean 上下文中获取。将范围设置为“原型”实际上不会做任何事情,因为处理程序(控制器)实际上只得到一次。

于 2012-10-18T11:12:22.720 回答
1

在这样的情况下,你违背了 Spring 的原则,我建议你可能正在以一种不被认为是最佳实践的方式做某事。没有更多的上下文很难看到。

Spring Social 使用request范围 bean 为特定用户体现存储库。我现在知道为什么,因为这是一种非常低效的做事方式,而且恕我直言,更难理解。

<bean id="connectionRepository" factory-method="createConnectionRepository"
    factory-bean="usersConnectionRepository" scope="request">
    <constructor-arg
        value="#{T(org.springframework.security.core.context.SecurityContextHolder).getContext().getAuthentication().getPrincipal()}" />
    <aop:scoped-proxy proxy-target-class="false" />
</bean>

您可以在此处看到在需要类的实例时使用factory-beanandfactory-method声明要调用的类/方法。构造函数参数使用 SpEL 传递。我不太确定如何使用 Spring MVC 响应 Web 请求来实现这一点,但我相当确定您可以使用 Spring Integration 传递消息并使用 SpEL 从该消息中获取标头/有效负载以传递给构造函数。

不过,我真的会在这里质疑您的设计模式——一个更常见的 SOA 习惯用法是在启动时创建服务,并从那里开始尽可能地让它们无状态,而不是为每个请求创建一个具有特定状态的实例。祝你好运!

于 2012-10-18T11:06:10.067 回答