ServletContext 和 spring ApplicationContext 的线程问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lml12377
V2EX    Java

ServletContext 和 spring ApplicationContext 的线程问题

  •  
  •   lml12377 2017-02-04 11:33:27 +08:00 3504 次点击
    这是一个创建于 3247 天前的主题,其中的信息可能已经有所发展或是发生改变。

    看到 spring 的 ServeltContextListener 加载方式时,有个问题。

    不知道我的理解对不对:

    tomcat 下一个 web 应用目录对应一个 ServeltContext 单例,假设使用 Servelt 处理请求,那一个 Servelt class 实在 tomcat 容器中也是单例,但是为了提升并发性能,这个单例可能会被多个线程使用。

    再到 spring ,在 servlet 被实例化这一步之前, spring 的 ContextLoaderListener 监听器被调用,通过 org.springframework.web.context.ContextLoader 创建 ApplicationContext 对象

    问题主要在 ApplicartionContext 这个地方:

    这个应用上下文是多线程的吗?因为看到了 static volatile 的 currentContext 和 ConcurrentHashMap 的 currentContextPerThread ,但是为什么还要保存一份当前线程 ContextClassLoader 管理的 WebApplicationContext ?直接用 Heap 区的那一份 currentContext 不行吗?还有,其它线程的 WebApplicationContext 又是在什么时机被创建出来的呢?

    5 条回复    2017-02-07 13:38:46 +08:00
    ihuotui
        1
    ihuotui  
       2017-02-04 23:02:33 +08:00 via iPhone   1
    看 web xml 然后看看到底有多少个 context ,看看启动过程。每个 context 的作用。
    yidinghe
        2
    yidinghe  
       2017-02-05 18:12:58 +08:00   1
    ServletContext 是一个 Servlet 对象对应的上下文环境,通常 Servlet 是单实例的,因此当你实现一个 Servlet 时,必须保证其线程安全性;至于 ServletContext ,一个 Servlet 对应的 ServletContext 对象也会一直保持在那里,是不会变的。

    一般来说,一个 Web 应用会有多个 Servlet ,而它们的 ServletContext 则是共用的一个。这个是由 Servlet 容器(如 Tomcat 、 Jetty )来决定。

    ApplicationContext 是 Spring Bean 的上下文环境,它的创建理论上与 ServletContext 无关,但在 SpringMVC 中,这个创建过程自动化了(具体是由 `org.springframework.web.servlet.DispatcherServlet` 触发的),并自动绑定到 ServletContext 下。

    ApplicationContext 本身当然是线程安全的,而且里面的 bean (就是你写的那些 Controller 和其他的相关类),缺省情况下也必须是线程安全的。

    WebApplicationContext 是 SpringMVC 中对 ApplicationContext 的具体实现,每个 ServletContext 下只会有一个 WebApplicationContext ,在应用初始化时就创建出来了,而不是等浏览器请求来了才创建。
    lml12377
        3
    lml12377  
    OP
       2017-02-07 10:04:10 +08:00
    @yidinghe 谢谢耐心的回答,还有一个问题请教一下:

    假设我的 web.xml 包含这样的配置:

    <listener>
    <listener-class>com.xxx.ContextLoaderListener</listener-class>
    </listener>
    <servlet>
    <servlet-name>business</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
    </servlet>

    ServletContext 是在 Servlet 之前初始化的:

    首先初始化并创建 ServletContext ,接着创建自定义的 ContextLoaderListener.contextInitialized 并把刚刚创建的 ServletContext 传递给它,看代码 WebApplicationContext 应该是在 ContextLoader.initWebApplicationContext 里创建出来的;接着才是 DispatcherServlet 的创建。

    你上面说的 [这个创建过程自动化了(具体是由 `org.springframework.web.servlet.DispatcherServlet` 触发的)],是不是指的是当我不指定 ContextLoaderListener 的情况?
    yidinghe
        4
    yidinghe  
       2017-02-07 11:28:54 +08:00   1
    可能我描述有不准确的地方。以代码为准就是了。
    lml12377
        5
    lml12377  
    OP
       2017-02-07 13:38:46 +08:00
    @yidinghe 谢谢~还是 v2 大神多,感觉比 seg 靠谱多了
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     4421 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 36ms UTC 04:02 PVG 12:02 LAX 20:02 JFK 23:02
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86