[英]How do I instantiate a new bean in a method call?
I have something like this: 我有这样的事情:
@Controller
@Scope("session")
public class MyServletController {
@Autowired
private QueryRunner queryRunner;
HashMap<String, Result> resultsMap;
@RequestMapping("/submitQuery")
public ModelAndView submitQuery(HttpServletRequest request)
{
String sessionId = request.getParameter("sessionId");
Result r = queryRunner.runQuery(sessionId, request.getParameter("otherdata"));
resultsMap.put(sessionId, r);
}
@RequestMapping("/getResult")
@ResponseBody
public void saveTextLinks(HttpServletRequest request,
HttpServletResponse response) throws IOException
{
String sessionId = request.getParameter("sessionId");
//return sessionId result from resultsMap
}
}
<bean id="queryRunner"
class="com.myproject.QueryRunner"
scope="prototype">
<aop:scoped-proxy />
<property name="errorMessageA" value="${error.messagea}"></property>
<property name="errorMessageB" value="${error.messageb}"></property>
</bean>
What I want is that the Servlet Controller is session scoped, but each request needs to instantiate a new QueryRunner
as to not have any interference if multiple requests are sent at once. 我想要的是Servlet控制器在会话范围内,但是每个请求都需要实例化一个新的QueryRunner
,以免一次发送多个请求时不会受到任何干扰。
How do I configure Spring to do this? 如何配置Spring来做到这一点?
The tempting solution is to just go: 诱人的解决方案是:
@RequestMapping("/submitQuery")
public ModelAndView submitQuery(HttpServletRequest request)
{
queryRunner = new QueryRunner(); //<-----
String sessionId = request.getParameter("sessionId");
Result r = queryRunner.runQuery(sessionId, request.getParameter("otherdata"));
resultsMap.put(sessionId, r);
}
[...] but each request needs to instantiate a new QueryRunner as to not have any interference if multiple requests are sent at once [...]但每个请求都需要实例化一个新的QueryRunner,以确保一次发送多个请求时不会受到任何干扰
Your setup already does that. 您的设置已经做到了。 Your QueryRunner
bean is declared as 您的QueryRunner
bean被声明为
<bean id="queryRunner"
class="com.myproject.QueryRunner"
scope="prototype">
<aop:scoped-proxy />
This means that Spring will inject a proxy wherever such a bean is requested, for example 这意味着Spring将在任何需要这种bean的地方注入代理,例如
@Autowired
private QueryRunner queryRunner;
and the proxy will, internally, delegate all calls to newly initialized beans every time. 并且代理将在内部每次将所有调用委派给新初始化的bean。 Note that this means that if you do something like 请注意,这意味着如果您执行类似
Result r1 = queryRunner.runQuery(sessionId, request.getParameter("otherdata"));
Result r2 = queryRunner.runQuery(sessionId, request.getParameter("evenmoredata"));
each of those runQuery
calls are, underneath it all, invoked on different QueryRunner
instances. 所有这些runQuery
调用都在不同的QueryRunner
实例下被调用。
If you want to have a single QueryRunner
bean that spans the entire lifecycle of a request, just declare the bean to have the request scope 如果您想拥有一个跨请求整个生命周期的QueryRunner
bean,只需声明该bean具有请求范围
<bean id="queryRunner"
class="com.myproject.QueryRunner"
scope="request">
<aop:scoped-proxy />
Behind the scenes (assuming the default MVC configuration), Spring will store a reference to the HttpServletRequest
in a ThreadLocal
context accessible through a static
utility class. 在幕后(假设使用默认的MVC配置),Spring将在对ThreadLocal
上下文的访问中存储对HttpServletRequest
的引用,该上下文可通过static
实用程序类访问。 It will store the actual bean in the HttpServletRequest
attributes. 它将实际的bean存储在HttpServletRequest
属性中。
When you eventually invoke runQuery
on the proxy (which is stored in the `@Autowired field), Spring will first check the context for a existing bean. 当您最终在代理上调用runQuery
时(存储在`@Autowired字段中),Spring将首先检查上下文中是否存在现有的bean。 If it finds one, it will use it to invoke your method. 如果找到一个,它将使用它来调用您的方法。 If it doesn't, it will initialize a new instance, store it in the context, then use it. 如果没有,它将初始化一个新实例,将其存储在上下文中,然后使用它。 This way, the previous example 这样,前面的例子
Result r1 = queryRunner.runQuery(sessionId, request.getParameter("otherdata"));
Result r2 = queryRunner.runQuery(sessionId, request.getParameter("evenmoredata"));
is actually invoking runQuery
on the same QueryRunner
instance. 实际上是在同一QueryRunner
实例上调用runQuery
。
Since HttpServletRequest
attributes are cleared after each request, so will your request-scoped bean instances. 由于在每个请求之后都会清除HttpServletRequest
属性,因此您的请求范围的Bean实例也会被清除。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.