SpringMvc获取HttpServletRequest 对象的方式

SpringMvc获取HttpServletRequest 对象的方式

1.@Autowired 方式
2.public void Test(HttpServletRequest request1, HttpServletResponse resp,HttpSession session1) 方式
3.((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest(); 方式
4.Global.getHttpServletRequest(); 方式,该方式基于 第三种做的封装



@Autowired
HttpServletRequest request的原理

拿到这个注解首先会很疑惑几个问题,如下
1.request这个对象是什么时候注册的?
2.每次请求都会有一个新的request,怎么能保证这个就是对应的每次请求的request
3.是否线程安全
下面就对这个问题进行一一解答
1.request这个对象是什么注册的?
SpringMvc的ApplicationContext是XmlWebApplicationContext
XmlWebApplicationContext继承AbstractRefreshableWebApplicationContext
现在重点在于AbstractRefreshableWebApplicationContext的postProcessBeanFactory的方法
调用链如下
AbstractRefreshableWebApplicationContext.postProcessBeanFactory
==> WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
==> {
    beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope());
    beanFactory.registerScope(WebApplicationContext.SCOPE_SESSION, new SessionScope());
    // 重点就是这一行了
    beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory());
    beanFactory.registerResolvableDependency(ServletResponse.class, new                ResponseObjectFactory());
    beanFactory.registerResolvableDependency(HttpSession.class, new SessionObjectFactory());
    beanFactory.registerResolvableDependency(WebRequest.class, new WebRequestObjectFactory());
}
1.首先HttpServletRequest注入
new RequestObjectFactory().getObject()
   //为社么调用getObject()?, 代码见AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType))
    ==> currentRequestAttributes().getRequest();
    ==>  { 
        currentRequestAttributes() 方法。
        RequestAttributes requestAttr = RequestContextHolder.currentRequestAttributes();
        if (!(requestAttr instanceof ServletRequestAttributes)) {
            throw new IllegalStateException("Current request is not a servlet request");
        }
        return (ServletRequestAttributes) requestAttr;
    }
所以主要是RequestContextHolder,从RequestContextHolder类可以看到主要用到了ThreadLocal,ThreadLocal主要可以保存当前的变量
那么问题又来了HttpServletRequest是何时放入RequestContextHolder中的。

2.有多个地方HttpServletRequest都可以进入RequestContextHolder中
 {
   1. FrameworkServlet(DispatcherServlet继承的它).processRequest
   ==> initContextHolders() ==> RequestContextHolder
   2. RequestContextListener (每次Http请求都会触发) 并将HttpServletRequest请求放入RequestContextHolder中
 }
 有个坑 就是文件上传用的是MultipartHttpServletRequest 而注入的是RequestFacade不是同一个,所以文件上传通过方法入参比较好,也就是第二种方法
3.由于采用的是ThreadLocal,HttpServletRequest维护到了当前所在的线程当中,所以是线程安全的。




实现ObjectFactory注入的时候调用getObject获取到对应的bean,和FactoryBean有点像
findAutowireCandidates
==> resolvableDependencies 
==> AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType)
==> factory.getObject();
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • (ps:前几个星期发生的事情)之前同事跟我说不要使用@Autowired方式注入HttpServletReques...
    cmazxiaoma阅读 7,431评论 4 23
  • 对于java中的思考的方向,1必须要看前端的页面,对于前端的页面基本的逻辑,如果能理解最好,不理解也要知道几点。 ...
    神尤鲁道夫阅读 844评论 0 0
  • 1.埋点是做什么的 2.如何进行埋点 3.埋点方案的设计 近期常被问到这个问题,我担心我的答案会将一些天真烂漫的孩...
    lxg阅读 2,036评论 0 1
  • SpringMVC介绍 Spring web mvc 和Struts2都属于表现层的框架,它是Spring框架的一...
    day_Sunny阅读 805评论 0 0
  • 夜,夜寂静如安魂曲 四周只有我的心跳声 白色的床单铺设着一条银河 我翻山越岭 而无法触及 手臂是萌生的邪恶山脉 上...
    行走主义阅读 195评论 0 0