问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

Springmvc中在controller注入request会有线程安全问题吗

发布网友 发布时间:2022-04-23 00:43

我来回答

2个回答

热心网友 时间:2023-06-28 14:16

servlet是单例的,而tomcat则是在多个线程中调用servlet的处理方法。因此如果servlet存在实例对象,那么就会引出线程安全的问题。而springmvc允许在controller类中通过@Autowired配置request、response以及requestcontext等实例对象。这种配置方法是否线程安全?答案是——这种配置方法是线程安全的,request、response以及requestcontext在使用时不需要进行同步。而根据spring的默认规则,controller对于beanfactory而言是单例的。即controller只有一个,controller中的request等实例对象也只有一个。然而tomcat依旧会以多线程的方式访问controller。这种做法似乎并不能保证线程安全。我们如何理解这一矛盾?
在解释controller线程安全这一问题之前需要首先了解如下的一些问题和概念:

1.servlet的request域的问题:request域是javaweb的基础概念,他指的是从发起http请求到返回响应的这一段时间内,存在一个httprequest对象对应于http请求。以上的表述是没有问题的,然而有些人“自作主张”的将之前的表述换成了其他的描述方式:(1):request对象的生命周期以发起http请求开始,当http请求返回时结束;(2):用户发送一个请求的时候,request被创建,当用户关闭请求的时候,request会消亡。以上两种表述的主要错误在于混淆了http请求和request对象这两个概念。tomcat在接收到http请求的时候并不会创建一个request对象,即request对象并不是一个http请求的实例。只是request对象“恰巧”拥有了http请求中的所有参数而已。request对象在tomcat发起处理线程的时候就被创建,只有当处理线程终止的时候request才会被销毁。我们可以创建一个servlet类,并在doget和dopost方法上面打上断点。你会发现如果是同一个进程,即便发起多次访问,request对象的id始终不变。读者可以亲自尝试,用以验证本人说法的真伪。

2.Threadlocal类:该对象包含两个关键函数:set(Object obj)和get()。这两个函数与调用该函数的线程相关,set方法将某一对象“注入”到当前线程中,而get方法则是从当前线程中获取对象。

3.InvocationHandler接口:这是springmvc保证request对象线程安全的核心。通过实现该接口,开发者能够在Java对象方法执行时进行干预,搭配Threadlocal就能够实现线程安全。

下面将通过例子介绍springmvc如何保证request对象线程安全:

Httprequest接口:

public interface HttpRequest {
public void service();
}

HttpRequestImpl类:对httprequest接口的具体实现,为了区别不同的HttpRequestImpl对象,本人为HttpRequestImpl设置了一个Double对象,如果不设置该对象,其默认为null

public class HttpRequestImpl implements HttpRequest{
public Double d;
@Override
public void service() {
System.out.println("do some serivce, random value is "+d);
}

}

ThreadLocalTest类:负责向ThreadLocal设置对象和获取对象,本人设置ThreadLocal对象为static,因此ThreadLocalTest类中只能有一个ThreadLocal对象。

public class ThreadLocalTest {
public static ThreadLocal<HttpRequest> local=new ThreadLocal<HttpRequest>();
public static void set(HttpRequest f){
if(get()==null){
System.out.println("ThreadLocal is null");
local.set(f);
}
}
public static HttpRequest get(){
return local.get();
}
}

Factory类:该类是一个工厂类并且是单例模式,主要负责向ThreadLocalTest对象中设置和获取对象

public class Factory{
private static Factory factory=new Factory();
private Factory(){

}
public static Factory getInstance(){
return factory;
}
public HttpRequest getObject(){
return (HttpRequest)ThreadLocalTest.get();
}
public void setObject(HttpRequest request){
ThreadLocalTest.set(request);
}
}

Delegate类:该类实现了InvocationHandler接口,并实现了invoke方法

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class Delegate implements InvocationHandler{
private Factory factory;

public Factory getFactory() {
return factory;
}

public void setFactory(Factory factory) {
this.factory = factory;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return method.invoke(this.factory.getObject(), args);
}

}

热心网友 时间:2023-06-28 14:16

controller默认是单例 需要的数据都从方法参数传递 只要不定义类变量 就安全 放心吧

@Controller
@RequestMapping("/fui")
public class FuiController extends SpringController {

这么定义的话就是单例

@Controller
@Scope("prototype")
@RequestMapping("/fui")
public class FuiController extends SpringController {
每次都创建

@Controller
@Scope("session")
@RequestMapping("/fui")
public class FuiController extends SpringController {
一个会话创建一个
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
是选诺顿杀毒软件好还是NOD32好? 诺顿好还是NOD32好???请高手指点 诺顿安全软件和ESET NOD32安全软件相比,谁的防护.杀毒更强,功能更多... 诺顿和NOD32这两个杀毒软件哪个比较好? 什么是土地二次抵押 "口似含莲,乾姜之手"是什么意思? 乾姜的意思是什么 都说Pinnacle Food公司各方面做的好,有对这家了解的吗 空调蒸发箱多久清洗一次 空调蒸发箱需要清洗吗 苹果xr流量设置 请问MVC的 httpcontext.request.requestcontext.routedata.value[&quot;controller&quot;]这句是什么意思? 如何从一个RequestContextHolder MultipartHttpServletRequest requestcontextlistener 和contextloaderlistener 可以在web.xml中同时配置么 requestcontextholder什么意思 JSP的context和page、request、session、application的属性有区别么? httpclient传文件 报The method parseRequest(RequestContext) 参数类型错误 RequestContextListener有什么用 request和ActionContext获取请求参数有什么区别 html 页面中 $(request.contextPath) 的应用有哪些条件,或是注意事项 RequestContext.REQUEST_REQUEST_CONTEXT是java中的那个包里? $和request.contextPath的区别 asp.net 中 request 与 context.request有什么区别? java 在servlet中怎么获得requestcontext 苏宁金融账号怎么修改绑定手机? 回力鞋正品一定是鞋后是回力两个字吗? 如果鞋后和鞋侧都是勾的那个符号是正品吗 怎么涂掉鞋子上回力二字? 鞋上有笔迹怎么去除 怎么去掉双星鞋上的字 怎么快速去除篮球鞋上用笔写上的字 怎么擦掉鞋子上的字迹 OPPO手机图形密码忘了怎么办? pageContext.request.contextPath无效 什么情况下 getrequestcontext.getcookievalue&quot;pspt ${pageContext.request.contextPath}与${ctx}有什么区别? ${pageContext.request.contextPath }是什么意思 请问OPPO手机忘记锁屏图案密码怎么办? 我是OPPO手机忘了解锁图案怎么办? 为什么request.getContextPath得到的路径为空 oppo手机解锁图案密码忘记了怎么办? oppo手机屏锁图案忘了怎么办? oppo手机忘了锁屏图案怎么办? OPPO手机忘记锁屏图案了在数据清除时要图案怎么办? 手机锁屏图案忘了怎么办?型号是OPPO a5型 国内十大猎头公司是哪些? 请问猎头公司十大都有哪些? 猎头公司十大都有哪些? 快消猎头公司哪家最好 快消猎头哪家公司在比较知名,推荐一下吧 快消品行业猎头哪家比较靠谱? 十大猎头机构谁能推荐一下?卫士蓝猎头公司实力如何?